Use read(2) in msg_get()

We use read() on the socket elsewhere, so might as well be consistent.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Produce a nice listing of messages once connected

e.g

+OK Mailbox open, 4 messages
   1: Test
       Andrew Clayton <andrew@digital-domain.net>
       Sun, 28 Apr 2013 12:20:09 +0100
   2: Test
       Andrew Clayton <andrew@digital-domain.net>
       Sun, 28 Apr 2013 00:28:46 +0100
   3: Test
       Andrew Clayton <andrew@digital-domain.net>
       Sun, 28 Apr 2013 00:04:55 +0100

When generating the list we use the TOP command to get the message
headers. We don't know how long the headers are so don't know how much
we need to read from the socket.

Currently I'm just looping for (;;) { reading from the socket until we
read in "\r\n\r\n.\r\n" } which would signify the end of the message
headers (at least in the POP server I'm testing against, my ISP's).

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Don't send just "\r\n" to the server

Handle cases where you might have pressed enter without any command etc.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Make 'exit' send a POP QUIT command

Cleaning up the applications exiting path in the process.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Add 'help' and 'listx' commands

'help' will display a list of some of the useful POP commands.
'listx' will redisplay the popx list of messages.

It's 'listx' to differenciate from the builtin POP LIST command.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Call msg_get() from msg_send()

This ensures we get any responses back at the time, so we don't end
up getting a previous reply when we go to read from the socket the next
time after a request.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Re-create the message list after a DELE command

When a message is deleted, it is only marked for deletion (RSET will
bring it back). So you send up with something like

    1 1118
    3 1100

after the 2nd message is marked for deletion. This caused a problem in
get_message_hdrs() as we used message - 1 for the message headers
structure array index. As in this case when it came to the second
message it would be trying to access msg_hdrs[2], which is invalid
memory.

So we need to use nr_messages - 1 as the array index, as this value
isn't linked to the message number.

We also need to reinitialise the msg_hdrs strcuture and nr_messages
counter in free_msg_hdrs().

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Zero out newly allocated msg_hdrs structures

In get_message_hdrs() we allocate a new msg_hrds structure array element
using realloc(). memset() this to 0 once allocated to cater for cases
where there are missing mail headers such as no subject, that could end
up with junk in them.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Use an index variable in get_message_hdrs()

Create a variable index = ++nr_messages - 1 for use as the array index
for the msg_hdrs structures.

This just makes things easier to read.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Remove a redundant line = NULL in get_message_hdrs()

This variable is used to store the return string from getline() and is
initialised to NULL at the start of each loop iteration.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Add the select file descriptors at the top of the loop

These are the file descriptors for stdin (command prompt) and the
network socket.

Rather than add them once outside the loop, then each time at the bottom
of loop, just add each time at the top of the loop.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Update the README

Mention the help command.

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>