> ## 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 Sampl e 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