Getting a head(er)

Once you know how many emails there are waiting you can use the TOP command to get the header of any of them.

This is not a difficult function to write but it is our first encounter with POP3 multi-line protocols. When the server sends a multi-line response it marks the end of it with a “.” followed by a carriage return, line feed pair.

You might think that all you have to do is send the TOP command and wait for the post office to send all the headers back. The complication is that it is possible that the post office will not send all of the headers in a single block of data.

In other words, you might well start processing a partial list of headers. To make sure that this doesn’t happen you have to test the end of the data received for a “.” at the end of a line. If you don’t find this then you need to wait for the completion of the data transmission and add the next block of incoming data to the temporary buffer.

The only refinement that this routine might need is to reset the timeout after each block has been received. Alternatively if this becomes a problem in practice the client could just increase the timeout before retrieving headers. Notice that the headers are returned as one long string ready for further processing.

The same trick of converting the reply string into a StringBuilder so that it can be built up efficiently is used. You might be wondering what the WaitFor("") is doing in the while loop. This simply reads the next block of data from the server and as we don't care what the block starts with the target string is set to the null string.

The same technique can be used to retrieve an entire email because it too is terminated by a “.” all on its own on a line.

If you are wondering what happens if a line in the message body is just a dot at the start of the line the answer is – byte stuffing. Any dots on line of there own have a single space character added and which needs to be removed when you retieve and process the body of the message.

The big problem with just downloading an email in this way is that it could be a bit on the big size if there are any file attachments included.

This could mean that you end up trying to store MBytes in RAM as a huge string. The full solution to this problem is to change the routine so that it always writes the incoming data to disk and passes the email on to the client as an unprocessed text file.

In this case a simpler solution is just not to download anything that is too big! To allow the client discover the size of an email without downloading it we can use the LIST command and the getNum function.

Before you decide that the two calls to getNum are a mistake it is worth pointing out that the size of the email is the second number returned and two calls are indeed necessary. The first value returned by getNum is simply an echo back of the email number.

Dumping the post

You can mark any email for delete by specifying its number and using the DELE command -

Notice that emails are only marked as deleted not actually removed from the mailbox by this command.

Even so you can’t manipulate emails marked as deleted. For example, if you try to get the size of an email after marking it for deletion then an error will be generated.

Also notice that marking an email for deletion doesn’t change the numbering of the emails.

If you want to actually delete all the emails that you have marked then you have to use the Quit command which also closes the connection to the post office. As long as the post office can delete the emails it returns an “+OK” and the next time you connect the marked emails are gone.

Getting access to the hardware is never easy from an application. If you want to know how well your disk drive is performing then there is a way of accessing the SMART data - including the temperature [ ... ]