Receiving Mail with POP3
Table of Contents | Previous | Next | Index

Messaging Access SDK Guide
Part 1. Using the Messaging Access SDK


Chapter 5
Receiving Mail with POP3

This chapter is an overview of using POP3 (Post Office Protocol 3) to download messages to a client.

[Top]

The POP3 Protocol

POP3 (Post Office Protocol 3) retrieves mail from mailboxes on a remote server. The server retains messages until the client requests them.

Unlike IMAP4, POP3 only receives mail. IMAP4 provides the capabilities of POP3 along with the ability to move messages back and forth between client and server, and manage mailboxes on the server. For information about IMAP4, see Chapter 4, "Receiving Mail with IMAP4."

POP3 commands use the ASCII character set. They are made up of a keyword, followed by any parameters the command has, and ending with "<CRLF>.<CRLF>." Commands are line-oriented and can return a single or multi-line response.

For detailed information about POP3, see RFC 1939: "Post Office Protocol - Version 3."

[Top]

POP3 Session States

A POP3 session progresses through three stages, or states. Within each state, only certain commands are possible.

Figure 5.1   POP3 Session States

Table 5.1 POP3 Session States and Commands

Session State Commands

Authorization

User login, password approval, quit. Commands: USER, PASS, QUIT

Transaction

Operations involving messages. Commands: STAT, LIST, RETR, DELE, NOOP, RSET, TOP, UIDL

Update

Delete any marked messages. The session enters this state after a QUIT command, deletes messages marked for deletion, then quits. Commands: QUIT

For a table of SDK-supported POP3 protocol commands that lists the state in which each can be called, see Supported POP3 Internet Protocol Commands. For detailed information about POP3 and POP3 session states, see POP3 RFCs.

[Top]

Steps in a POP3 Session

Generally, a messaging application follows these steps when using POP3 to receive mail. These steps are listed below with links to more detailed descriptions.

Step Section with details

Initialize the response sink.

Creating a Response Sink

Create a client.

Creating a Client

Connect to the server.

Connecting to a Server

Log in to the server.

Logging In

Get the message count.

Getting Message Count

List messages on the server.

Listing Messages

Retrieve the message headers.

Retrieving Message Headers

Retrieve messages themselves.

Retrieving a Message

End the POP3 session.

Ending the Session

[Top]

POP3 Response Codes

When a client sends a POP3 command, a text response code is returned with descriptive text. The response can either be single- or multi-line.

Table 5.2 POP3 Response Types

Response Type Response Code and Description

Single line

Multi-line

First line: Like single-line response:

Subsequent lines: More information about the condition.

Final line: . (dot) and <CRLF>. (Not considered part of the response.)

Note: If an error occurs on a multi-line response, a single line is returned.

For a list of functions and their associated callbacks, see POP3 Function Callback Mapping.

[Top]

POP3 Function Callback Mapping

Callbacks are associated with many POP3 functions. For general information about the response sink and callbacks, see SDK Response Sinks for C.

The pop3Sink_t structure contains callbacks for each client call. The client's processResponses function invokes the interface function that corresponds to the client call. Functions with multi-line responses map to more than one callback. The first type of callback indicates the start of a notification. The second type passes back multi-line data. The third type of callback provides a notification that the operation is complete.

If a server error occurs, the error callback is invoked.

Table 5.3 shows which POP3 functions are mapped to callbacks in the pop3Sink_t structure. Table 5.4 shows functions that do not map to callbacks.

Table 5.3 Functions with Callbacks

Functions Possible Responses, Mapped to Callbacks
pop3_connect
connect, error 
pop3_delete 
dele, error 
pop3_list 
listStart, list, listComplete, error 
pop3_listA 
listStart, list, listComplete, error 
pop3_noop 
noop, error 
pop3_pass 
pass, error 
pop3_quit 
quit, error 
pop3_reset 
reset, error
pop3_retrieve 
retrieveStart, retrieve, retrieveComplete, error
pop3_sendCommand 
sendCommandStart, sendCommand, sendCommandComplete, error
pop3_stat 
stat, error
pop3_top 
topStart, top, topComplete, error
pop3_uidList 
uidListStart, uidList, uidListComplete, error
pop3_uidListA 
uidListStart, uidList, uidListComplete, error
pop3_user 
user, error
pop3_xAuthList 
xAuthListStart, xAuthList, xAuthListComplete, error
pop3_xAuthListA 
xAuthListStart, xAuthList, xAuthListComplete, error
pop3_xSender 
xSender, error
Table 5.4 Functions without Callbacks

Functions Without Callbacks
pop3_free 
pop3_setResponseSink 
pop3_disconnect 
pop3_setTimeout 
pop3_get_option 
pop3_set_option 
pop3_initialize 
pop3Sink_free 
pop3_processResponses 
pop3Sink_initialize 
pop3_setChunkSize 
 
[Top] [POP3 Function Callback Mapping]


Creating a Response Sink

The first step in starting a POP3 session is to initialize the POP3 response sink, which is defined by the pop3Sink_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 pop3Sink_initialize function and supply the sink you want the POP3 client to use. If successful, this function returns NSMAIL_OK. Use this syntax:

int pop3Sink_initialize( pop3Sink_t ** out_ppPOP3Sink )
The following section of code initializes the response sink and sets the sink function pointer.

int l_retCode = 0; 
pop3Sink_t * l_pPOP3Sink = NULL; 
l_retCode = pop3Sink_initialize(&l_pPOPSink); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
setSinkFunctions(l_pPOP3Sink); 
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 this function:

void pop3Sink_free( pop3Client_t ** in_ppPOP3Sink );
When this function returns, the response sink is set to null. The user must free any opaque data.

After you create the response sink, the next step is Creating a Client.

[Top] [Creating a Response Sink]

Creating a Client

The POP3 client uses the pop3Client_t structure to communicate with a POP3 server. To initialize and allocate the pop3Client_t structure and set the response sink for the client's use, call the pop3_initialize function.

When you create the client structure, you supply the identifier of the POP3 client you are creating, along with an initialized response sink, as described in Creating a Response Sink. Use this syntax:

int pop3_initialize( pop3Client_t ** out_ppPOP3, 
                     pop3SinkPtr_t in_pPOP3Sink );
The following section of code creates a client.

/* Initialize sink first as described in Creating a Response Sink */
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_initialize(&l_pPOP3Client, l_pPOP3Sink); 
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 pop3_free( pop3Client_t ** in_pPOP3 );
The in_pPOP3 parameter represents the POP3 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]

Connecting to a Server

Before it can retrieve mail, the client must connect with the server through a service port. To connect to the server, use the pop3_connect function.

Supply the identifier of the POP3 client that wants to connect with the server. If the server is using the default port for the POP3 protocol (port 110), you can enter 0 as the value of the port parameter. The SDK function performs some error-checking. Use this syntax:

int pop3_connect( pop3Client_t * in_pPOP3, 
                  const char * in_server,
                  unsigned short in_port );
NOTE: For this function's callback mapping, see POP3 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 = "pop3Server.com"; 
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_connect(l_pPOP3Client, l_szServer, 110); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
After connecting, the next step is Logging In.

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 pop3_disconnect( pop3Client_t * in_pPOP3 );
The in_pPOP3 parameter represents the POP3 client. This function could be useful as part of a Cancel operation while retrieving a message. Remember that you do not call pop3_processResponses after pop3_disconnect.

NOTE: For the callback mapping for these functions, see POP3 Function Callback Mapping. §
[Top]

Logging In

Once the client is connected to the server, the user can log in. Login identifies the client to the server. Logging in requires the identifier of the POP3 client, as well as the user's ID and plain text password.

First, call pop3_user and pass the POP3 client and the user name. Use this function:

int pop3_user( pop3Client_t * in_pPOP3, const char * in_user );
This function sends the USER POP3 protocol command.

To submit the user password, call the pop3_pass function:

int pop3_pass( pop3Client_t * in_pPOP3, 
            const char * in_password );
This function sends the PASS POP3 protocol command.

While these commands execute, the session is in Authorization state. Successful completion moves the session to the Transaction state. For a list of states and commands that can be executed in each state, see POP3 Session States.

A successful login moves the POP3 session from the Authorization state to the Transaction state, where the user can perform a number of operations.

NOTE: For the callback mapping for these functions, see POP3 Function Callback Mapping. §
The following section of code logs the user in with user name and password.

/* User id sequence */
int l_retCode = 0; 
char* l_szUser = "test1"; 
char* l_szPassword = "test1Password"; 
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_user(l_pPOP3Client, l_szUser); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
/* Password sequence */
l_retCode = pop3_pass(l_pPOP3Client, l_szPassword); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
After you log in, you can perform any Transaction state operations. The next step is Retrieving a Message.

[Top]

Getting Message Count

In the POP3 Transaction state, the client can find out how many messages are present by requesting the status of the mail drop or mailbox. The pop3_stat function gets the mailbox status for a given client by issuing the STAT protocol command. Use this function:

int pop3_stat( pop3Client_t * in_pPOP3 );
The status returned includes the number of messages present and the octet size of the mail drop.

NOTE: For this function's callback mapping, see POP3 Function Callback Mapping. §
The following section of code counts the messages in the client's mailbox.

int l_retCode = 0; 
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_stat(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
[Top]

Listing Messages

To list messages while in the POP3 Transaction state, call either of two functions, depending on whether you want to list all of the messages in a mailbox or a specific message.

To go through all the messages in the mailbox and generate a list of messages, use the pop3_list function:

int pop3_list( pop3Client_t * in_pPOP3 );
This function takes only the POP3 client as a parameter. It sends the LIST POP3 protocol command.

To list only the message specified by the message number, use the pop3_listA function:

int pop3_listA( pop3Client_t * in_pPOP3, int in_messageNumber );
Supply the POP3 client and a message number as parameters. This function sends the LIST [arg] POP3 protocol command.

NOTE: For the callback mapping for these functions, see POP3 Function Callback Mapping. §
The following section of code retrieves the email address of the sender along with authenticated messages.

int l_retCode = 0; 
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_list(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
[Top]

Retrieving Message Headers

In the Transaction state, the user can preview mailbox contents or part of a long message before deciding to download it by listing the headers plus some of the lines of the body. The user (or the mail application) determines the number of message lines to retrieve.

To identify the message, supply the number of the message and the number of body lines to retrieve. Use the pop3_top function, which issues the TOP protocol command:

int pop3_top(pop3Client_t * in_pPOP3, 
             int in_messageNumber, int in_lines );
To retrieve all headers for a given mailbox, combine pop3_top with a call to pop3_stat. First, call pop3_stat to find the number of messages in the mailbox. When you get the number, for example, 10, call pop3_top once, passing each message number in turn, until you get to the total (in this case, 10). For the in_lines parameter, use a value of 0 so that no body lines are returned.

NOTE: For this function's callback mapping, see POP3 Function Callback Mapping. §
The following section of code lists the header of the message specified by its message number. It retrieves no body lines.

int l_retCode = 0; 
int l_messageNumber = 1; 
pop3Client_t * l_pPOP3Client = NULL; 
/* Get only the message headers: request 0 body lines */
l_retCode = pop3_top(l_pPOP3Client, l_messageNumber, 0); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
After you retrieve message headers, you can go on to Retrieving a Message if you like.

[Top]

Retrieving a Message

Retrieving a message is one of the most common activities that users want to perform during the POP3 Transaction state.

The pop3_retrieve function takes the identifier of the POP3 client that is retrieving the mail and and the message number, and retrieves the contents of the message:

int pop3_retrieve( pop3Client_t * in_pPOP3, int in_messageNumber );
The message is returned in the form of data chunks. The pop3_retrieve function issues a RETR command. It fails if the message with the specified number does not exist.

NOTE: For this function's callback mapping, see POP3 Function Callback Mapping. §
The following section of code retrieves the contents of a message.

int l_retCode = 0; 
int l_messageNumber = 1; 
pop3Client_t * l_pPOP3Client = NULL; 
l_retCode = pop3_retrieve(l_pPOP3Client, l_messageNumber); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
[Top]

Ending the Session

When the client wants to close the session, the messaging application must deallocate the response sink, free the client, and close the socket connection with the server. For these operations, see Connecting to a Server, Creating a Client, and Creating a Response Sink.

The client calls pop3_quit to notify the server that it is closing the session:

int pop3_quit( pop3Client_t * in_pPOP3 );
This function sends the QUIT POP3 protocol command. The server closes the TCP connection and sends back a response. It is preferable to end a session with pop3_quit instead of just closing.

If the session is in the Authentication state when this function is called, the server simply closes the connection. If the session is in the Transaction state, the server goes into the Update state and expunges any messages marked for deletion, and then quits.

NOTE: For this function's callback mapping, see POP3 Function Callback Mapping. §
The following section of code notifies the server that the client is terminating the session.

int l_retCode = 0; 
pop3Client_t * l_pPOP3Client = NULL;
l_retCode = pop3_quit(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
l_retCode = pop3_processResponses(l_pPOP3Client); 
if (l_retCode != NSMAIL_OK) { /*Deal with error*/ } 
[Top]

POP3 Functions by Task

To help you find the information you need more quickly, look for the task you want to perform in the column on the left. Then you can click the function name for further information.

Table 5.5 POP3 Functions by Task

Task Function for the task

Connect to server.

pop3_connect

Mark a message for deletion on the server.

pop3_delete 

Disconnect from server.

pop3_disconnect 

Free the POP3 client structure and its data members.

pop3_free 

Get the IO model.

pop3_get_option 

Initialize and allocate the POP3 client structure and set the sink.

pop3_initialize 

List all messages.

pop3_list 

List the specified message.

pop3_listA 

Contact the server, which sends a response indicating it is still present.

pop3_noop 

Identify user password and enter the Transaction state.

pop3_pass 

Process the server responses for API commands.

pop3_processResponses

Close the connection with the server.

pop3_quit 

Undelete any messages marked as deleted.

pop3_reset 

Retrieve message with specified number.

pop3_retrieve 

Send an unsupported command to the server.

pop3_sendCommand 

Set the size of the message data chunk passed to the user.

pop3_setChunkSize 

Set the IO models.

pop3_set_option 

Set a new response sink.

pop3_setResponseSink 

Set the amount of time allowed to wait before returning control to the user.

pop3_setTimeout 

Get the status of the mail drop.

pop3_stat 

Retrieve the headers plus a specified number of lines from the message.

pop3_top 

Get the message numbers and the corresponding unique ids of the messages in the maildrop.

pop3_uidList 

Get the specified message number and its unique id.

pop3_uidListA 

Enter a user name.

pop3_user 

Get a list of authenticated users.

pop3_xAuthList 

Get the authenticated user for a given message.

pop3_xAuthListA 

Get the email address of the sender of the specified message.

pop3_xSender 

Free the POP3 response sink and its data members.

pop3Sink_free 

Initialize and allocate the POP3 response sink structure.

pop3Sink_initialize 
[Top] [POP3 Functions by Task]


Table of Contents | Previous | Next | Index

Last Updated: June 3, 1998

Copyright © 1998 Netscape Communications Corporation