bdat
command, data chunking, and DSN. For more information, see Determining ESMTP Support.
During a single SMTP session, the client can send multiple unrelated, independently addressed messages. Because of this, the SMTP client can increase efficiency by batching messages and sending them together using pipelining. For more information, see Pipelining Commands.
The SMTP server waits for SMTP messages on the "well-known" TCP port 25. Many mail applications allow the user to specify a different port.
For a table of SDK-supported SMTP protocol commands, see Supported SMTP Internet Protocol Commands. For detailed information about SMTP, consult one of the RFCs listed, with links, in SMTP RFCs.
[Top]
Step |
Section with details
|
|
|
Determine Extended SMTP (ESMTP)
|
|
|
|
| |
---|
smtpSink_t
.
This table lists some of the most common SMTP reply codes. In general, response codes in the 100 to 300 range are considered successful; those in the 400 to 500 range are considered unsuccessful.
Table 2.1 SMTP Reply Codes
Code |
Text of Response
|
|
|
|
|
|
| <domain> servers not available, closing transmission channel
|
|
|
|
|
|
|
|
|
|
|
|
| |
---|
Digit 1 | Meaning |
1yz | |
2yz | |
3yz | |
4yz | |
5yz |
smtpSink_t
structure contains callbacks for each client call. The SMTP client's
smtp_processResponses
call invokes the corresponding interface function. This function reads in responses from the server and invokes the appropriate response sink functions. It thus invokes the callback functions provided by the user for all responses that are available at the time of execution.
If a time-out occurs, the user can continue by calling smtp_processResponses
again.
Functions with multi-line responses map to more than one callback. The second callback provides a notification that the operation is complete.
If a server error occurs, the error callback is invoked.
Table 2.3 shows which SMTP functions are mapped to callbacks in the
smtpSink_t
structure. Table 2.4 shows which do not map to callbacks.
Table 2.3 Functions with Callbacks
smtpSink_t
structure. The response sink is made up of function pointers and opaque data. Initializing the sink sets its function pointers and opaque data to null
. For general information about the response sink, see SDK Response Sinks for C.
To initialize and allocate the response sink, call the smtpSink_initialize
function and supply the sink you want the SMTP client to use. If successful, this function returns
NSMAIL_OK
. Use this syntax:
int smtpSink_initialize( smtpSink_t ** out_ppsmtpSink );The following section of code initializes the response sink and sets the sink function pointer.
int l_retCode = 0;
l_retCode = smtpSink_initialize(&l_psmtpSink);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
setSinkFunctions(l_psmtpSink);After you create the response sink, the next step is Creating a Client. When a session is finished, you must free any memory associated with the response sink. To free the response sink and its data members, use
smtpSink_free
:
void smtpSink_free( smtpSink_t ** in_ppsmtpSink );When this function returns, the response sink is set to
null
. The user must free any opaque data.
[Top] [Creating a Response Sink]
smtpClient_t
structure to communicate with an SMTP server. To initialize and allocate the smtpClient_t
structure and set the response sink for the client's use, call the
smtp_initialize
function.
When you create the client structure, you supply the address of the pointer to the SMTP client you are creating, along with an initialized response sink, as described in Creating a Response Sink. Use this syntax:
int smtp_initialize( smtpClient_t ** out_ppSMTP,The following section of code creates a client.
smtpSink_t * in_psmtpSink );
/* Initialize sink first as described in Creating a Response Sink */
l_retCode = smtp_initialize(&l_psmtpClient, l_psmtpSink);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }When a session is finished, you must free any memory associated with the client. To free the client structure and its data members, use this function:
void smtp_free( smtpClient_t ** in_psmtp_Client );The
in_psmtp_Client
parameter represents the SMTP client. When this function returns, the client structure is set to null
.
After you initialize the client, the next step is Connecting to a Server.
[Top]smtp_connect
function.
This function requires the identifier of the SMTP client that wants to connect with the server. If the server is using the default port for the SMTP protocol (port 25), you can pass 0 as the value of the port parameter. Use this syntax:
int smtp_connect(smtp_t * in_pSMTP,On connecting, the server sends a greeting message to the client. The client responds by identifying itself with the EHLO command.
const char * in_server,
unsigned short in_port );
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §The following section of code connects the client to the server.
/* After Creating a Response Sink and Creating a Client */
int l_retCode = 0;
char* l_szServer = "smtpServer.com";
l_retCode = smtp_connect(l_psmtpClient, l_szServer, 25);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }During the connect process, you can enable pipelining if your server supports it. See Pipelining Commands. To find out which extensions are supported by the server, see Determining ESMTP Support. After connecting to the server, the next step is Setting the Mailer. When a session is finished, you must free any memory associated with the client. To disconnect the client from the server and close the socket connection, use this function.
int smtp_disconnect( smtpClient_t * in_pSMTP );The
in_pSMTP
parameter represents the SMTP client. You can use this function as part of a Cancel operation while retrieving a message. Remember that you do not call smtp_processResponses
after smtp_disconnect
.
[Top]smtp_ehlo
function. This function returns a multiline message listing the Extended SMTP (ESMTP) features, such as pipelining or DSN, that the server supports. This is similar to the functionality of the IMAP4 capability
command. Use this syntax:
int smtp_ehlo( smtpClient_t * in_pSMTP,This function calls the EHLO SMTP protocol command, which can be issued in any session state, but is usually issued after connecting to the server.
const char * in_domain );
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §The following section of code finds out which Extended SMTP (ESMTP) features the server supports.
/* After Connecting to a Server */
int l_retCode = 0;
l_retCode = smtp_ehlo(l_psmtp, l_szDomainName);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }You can enable pipelining if your server supports this extension. See Pipelining Commands. [Top]
smtp_processResponses
function is called, if the internal storage area is full, or if a function that cannot be pipelined is issued.
You can enable pipelining anywhere, but it may make sense to do this after invoking the
smtp_ehlo
function. Pipelining may then be enabled if the server supports it. If not, the way the network works does not change. The ehlo
callback indicates whether pipelining is supported.
Use this syntax to attempt to enable pipelining:
int smtp_setPipelining( smtpClient_t * in_pSMTP,The
boolean in_enablePipelining );
in_pSMTP
parameter represents the client. The in_enablePipelining
parameter is a Boolean value that tells the server to attempt to enable pipelining. This function sends the PIPELINING SMTP protocol command.
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §Some functions continue to add to the pipelining list. These are
smtp_bdat
,
smtp_mailFrom
,
smtp_rcptTo
, and
smtp_sendStream
. Calling any other function causes the commands on the pipelining list to be sent.
For example, you could call smtp_mailFrom
, followed by one or more calls to smtp_rcptTo
. These functions are added to the pipelining list and are not executed. If you then call another function, such as smtp_noop
, the commands are sent to the server.
For details about using pipelining, refer to RFC 1854, "SMTP Service Extension for Command Pipelining."
[Top]in_esmtpParams
parameter. Use this function:
int smtp_mailFrom(smtpClient_t * in_pSMTP,The function identifies the sender and provides the sender's fully qualified domain name in the
const char * in_reverseAddress,
const char * in_esmtpParams );
in_reverseAddress
parameter. It sends the MAIL FROM: SMTP protocol command.
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §The following section of code sets the mailer.
/* After Connecting to a Server */
int l_retCode = 0;
char* l_szServer = "smtpServer.com";
char* l_szDomainName = "netscape.com";
char* l_szMailer = "derekt@netscape.com";
l_retCode = smtp_mailFrom(l_psmtp, l_szMailer, NULL);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }After you set the mailer, the next step is Setting the Recipient. [Top]
int smtp_rcptTo(smtpClient_t * in_pSMTP,This function sets a single recipient, so you must call it again for each recipient of a message. The
const char * in_forwardAddress,
const char * in_esmtpParams );
in_pSMTP
parameter represents the client. The in_forwardAddress
parameter supplies the recipient's address. If your server supports Extended SMTP, you can pass ESMTP elements in the in_esmtpParams
parameter.
smtp_ rcptTo
sends the RCPT TO SMTP protocol command.
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §The following section of code sets the recipient.
/* After Setting the Mailer */
int l_retCode = 0;
char* l_szRecipient = "alterego@netscape.com";
smtpClient_t * l_psmtpClient = NULL;
l_retCode = smtp_rcptTo(l_psmtp, l_szRecipient, NULL);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }After you set the recipient, the next step is Sending the Message. [Top]
smtp_data
, followed by either the smtp_send
or the smtp_sendStream
function. First, use this function:
int smtp_data( smtpClient_t * in_pSMTP );Supply the identifier of the SMTP client that is sending the mail. The server responds with a success or failure reply code. See SMTP Response Codes. The
smtp_send
and
smtp_sendStream
functions both deliver data to the server. smtp_send
sends data in a single chunk, while smtp_sendStream
sends the data in a series of smaller chunks. If you use either of these functions, you must send data with the smtp_data
function and not with smtp_bdat
.
smtp_data
and smtp_bdat
are interchangeable, but cannot be used together. The smtp_bdat
function, which can deliver binary data, is not supported on the Netscape Messaging Server and some other servers.
After the data
function, call smtp_send
, which sends a message to the server:
int smtp_send( smtpClient_t * in_pSMTP, const char * in_data );Supply the identifier of the SMTP client that is sending the mail and the identifier for the data to send. When the server responds that it is ready, the client sends the RFC 822 message data line by line. You can set data chunk size with
smtp_setChunkSize
, or you can use the default (1 K). You can set this to specify the chunk sizes used by the
smtp_sendStream
function.
The smtp_sendStream
function, like smtp_send
, sends a message to the server.
int smtp_sendStream( smtpClient_t * in_pSMTP,Supply the identifier of the SMTP client that is sending the mail and the identifier for the input stream.
nsmail_inputstream_t * in_inputStream );
NOTE: For the callback mapping for these functions, see SMTP Function Callback Mapping. §The following section of code uses
smtp_data
and smtp_send
to send a message.
smtpClient_t * l_psmtpClient = NULL;
/*Sending the Message*/
/* Start by sending identifier of sender */
l_retCode = smtp_data(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
/*Send the Message with smtp_send */
l_retCode = smtp_send(l_psmtpClient, "Hi how are you today?");
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }After you send the message and perform any other SMTP operations you need for the session, the next step is Ending the Session. [Top]
smtp_quit
to notify the server. The server closes the TCP connection and returns a response code. It is preferable to end a session with smtp_quit
instead of just closing the connection. This function sends the QUIT SMTP protocol command:
int smtp_quit( smtpClient_t * in_pSMTP );Supply the identifier of the SMTP client that wants to end the session.
NOTE: For this function's callback mapping, see SMTP Function Callback Mapping. §The following section of code notifies the server that the client is terminating the session.
int l_retCode = 0;
smtpClient_t * l_psmtpClient = NULL;
l_retCode = smtp_quit(l_psmtp);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }
l_retCode = smtp_processResponses(l_psmtpClient);
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ }[Top]
Last Updated: June 3, 1998