PREV NEXT INDEX



9. POP3 Client

Post Office Protocol version 3 (POP3) is probably the most common way of retrieving e-mail from a remote server. Most e-mail programs, such as Eudora, MS-Outlook, and Netscape's e-mail client, use POP3. The protocol is a fairly simple text-based chat across a TCP socket, normally using TCP port 110.

There are two ways of using POP3.LIB. The first method provides a raw dump of the incoming e-mail. This includes all of the header information that is sent with the e-mail, which, while sometimes useful, may be more information than is needed. The second method provides a parsed version of the e-mail, with the sender, recipient, subject-line, and body-text separated out.

In both methods, each line of e-mail has CRLF stripped from it and `\0' appended to it.

9.1 Configuration

The POP3 client can be configured through the following macros:

POP_BUFFER_SIZE

This will set the buffer size for POP_PARSE_EXTRA in bytes. These are the buffers that hold the sender, recipient and subject of the e-mail. POP_BUFFER_SIZE defaults to 64 bytes.

POP_DEBUG

This will turn on debug information. It will show the actual conversation between the device and the remote mail server, as well as other useful information.

POP_NODELETE

This will stop the POP3 library from removing messages from the remote server as they are read. By default, the messages are deleted to save storage space on the remote mail server.

POP_PARSE_EXTRA

This will enable the second mode, creating a parsed version of the e-mail as mentioned above. The POP3 library parses the incoming mail more fully to provide the Sender, Recipient, Subject, and Body fields as separate items to the call-back function.

9.2 Three Steps to Receive E-mail.

  1. pop3_init()is called to provide the POP3 library with a call-back function. This call-back will be used to provide you the incoming data. This function is usually called once.
  2. pop3_getmail() is called to start the e-mail being received, and to provide the library with e-mail account information.
  3. pop3_tick() is called as long as it returns POP_PENDING, to actually run the library. The library will call the function you provided several times to give you the e-mail.

9.3 Call-Back Function

There are two types of call-back functions, depending on if POP_PARSE_EXTRA is defined and will be handled separately.

9.3.1 Normal call-back

When not using POP_PARSE_EXTRA, you need to provide a function with the following prototype:


int storemail(int number, char *buf, int size);

number is the number of the e-mail being transferred, usually 1 for the first, 2 for the second, but not necessarily. The numbers are only guaranteed to be unique between all e-mails transferred.

buf is the text buffer containing one line of the incoming e-mail. This must be copied out immediately, as the buffer will be different when the next line comes in, and your call-back is called again.

size is the number of bytes in buf.

See pop.c in the Dynamic C Sample folder for an example of this style of call-back.

9.3.2 POP_PARSE_EXTRA call-back

If POP_PARSE_EXTRA is defined, you need to provide a call-back function with the following prototype:


int storemail(int number, char *to, char *from, char *subject, char *body, int size);

number, body, and size are the same as before.

to has the e-mail address of who this e-mail was sent to.

from has the e-mail address of who sent this e-mail.

subject has the subject line of the e-mail.

These new fields should only be used the first time your call-back is called with a new number field. In subsequent calls, these fields are not guaranteed to have accurate information.

See parse_extra.c in Section 9.5 for an example of this type of call-back.

9.4 Functions


pop3_init



int pop3_init(int (*storemail)());

Description

This function must be called before any other POP3 function is called. It will set the call-back function where the incoming e-mail will be passed to. This probably should only be called once.

Parameters

storemail

A function pointer to the call-back function.

Return value

0: Success.
1: Failure.

Library

POP3.LIB


pop3_getmail



int pop3_getmail(char *username, char *password, long server);

Description

This function will initiate receiving e-mail (a POP3 request to a remote e-mail server). IMPORTANT NOTE - the buffers for username and password must NOT change until pop3_tick() returns something besides POP_PENDING. These values are not saved internally, and depend on the buffers not changing.

Parameters

username

The username of the account to access.

password

The password of the account to access.

server

The IP address of the server to connect to, as returned from resolve().

Return value

0: Success.
1: Failure.

Library

POP3.LIB


pop3_tick



int pop3_tick(void)

Description

A standard tick function, to run the daemon. Continue to call it as long as it returns POP_PENDING.

Return value

POP_PENDING: Transfer is not done; call pop3_tick again.
POP_SUCCESS: All e-mails were received successfully.
POP_ERROR: Unknown error occurred.
POP_TIME: Session timed-out. Try again, or use POP_TIMEOUT to increase the time-out length.

Library

POP3.LIB

9.5 Sample Receiving of E-mail

This program connects to a POP3 server and downloads e-mail form it.

Program Name: /samples/tcpip/pop3/parse_extra.c

#define MY_IP_ADDRESS "10.10.6.105"   // change these configuration macros
#define MY_NETMASK "255.255.255.0" // to match your host.
#define MY_GATEWAY "10.10.6.1"
#define MY_NAMESERVER "10.10.6.254"

#define POP_HOST mail.domain.com"  //enter the name of your POP3 server

#define POP_USER "myname" //enter username for POP3 account
#define POP_PASS "secret" //enter password for POP3 account

#define POP_PARSE_EXTRA
#memmap xmem
#use "dcrtcp.lib"
#use "pop3.lib"
int n;

int storemsg(int num, char *to, char *from, char *subject, char *body, int len){
#GLOBAL_INIT{n = -1;}
if(n != num) {
n = num;
printf("RECEIVING MESSAGE <%d>\n", n);
printf("\tFrom: %s\n", from);
printf("\tTo: %s\n", to);
printf("\tSubject: %s\n", subject);
}
printf("MSG_DATA> '%s'\n", body);
return 0;
}
main(){
static long address;
static int ret;

   sock_init();
pop3_init(storemsg); //set up call-back function

printf("Resolving name...\n");
address = resolve(POP_HOST);
printf("Calling pop3_getmail()...\n");
pop3_getmail(POP_USER, POP_PASS, address); // POP3 request to server

printf("Entering pop3_tick()...\n");
while((ret = pop3_tick()) == POP_PENDING)
continue;
if(ret == POP_SUCCESS)
printf("POP was successful!\n");
if(ret == POP_TIME)
printf("POP timed out!\n");
if(ret == POP_ERROR)
printf("POP returned a general error!\n");
printf("All done!\n");
}

9.5.1 Sample Conversation

The following is an example POP3 session from the specification in RFC1939. For more information see:
http://www.rfc-editor.org/rfc/std/std53.txt

In the following example, lines starting with `S:' are the server's message, and lines starting with `C:' are the client's messages.


      S: <wait for connection on TCP port 110>
C: <open connection>
S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us>
C: APOP mrose c4c9334bac560ecc979e58001b3e22fb
S: +OK mrose's maildrop has 2 messages (320 octets)
C: STAT
S: +OK 2 320
C: LIST
S: +OK 2 messages (320 octets)
S: 1 120
S: 2 200
S: .
C: RETR 1
S: +OK 120 octets
S: <the POP3 server sends message 1>
S: .
C: DELE 1
S: +OK message 1 deleted
C: RETR 2
S: +OK 200 octets
S: <the POP3 server sends message 2>
S: .
C: DELE 2
S: +OK message 2 deleted
C: QUIT
S: +OK dewey POP3 server signing off (maildrop empty)
C: <close connection>
S: <wait for next connection>

For debugging purposes, you can observe this conversation by defining POP_DEBUG at the top of your program.


Z-World
http://www.zworld.com
Voice: 530.757.3737
Fax: 530.757.3792 or 530.753.5141
sales@zworld.com
PREV NEXT INDEX