cURL / Mailing Lists / curl-library / Single Mail


[PATCH] POP3: Expanded the supported commands

From: Steve Holme <>
Date: Sat, 10 Dec 2011 13:59:09 +0000

Dear all,

I wasn't sure whether to send my modifications through in one job lot or to
break it down into multiple submissions. In the end I went for one email but
have broken the modification down into 8 separate patches:

The first 5 patches are related to modifying pop3.c and pop3.h to include
support for the following POP3 commands in addition to LIST and RETR:

NOOP No Operation (Keep Alive)
STAT Get Mailbox Statistics
TOP Get TOP number of rows for specified message
DELE Delete specified message
RSET Reset (Undo any deletes)

Patches 6 and 7 are related to documentation updates for POP3

Patch 8 is a small documentation update for the optional SIZE parameter I
added to the MAIL FROM command a while ago in SMTP.

I have implemented support for the above commands using curl's -X and
libcurls CURLOPT_CUSTOMREQUEST options rather than as URLs as I had
previously suggested.

To implement the sending of these commands, I have kept in keeping with the
state machine of how POP3 and SMTP work rather than trying to devise a more
generic way of sending the commands. As such, a reference to the command is
stored in the local pop3c struct by pop3_parse_url_path() as I didn't want
to keep referencing conn->data-set.str[STRING_CUSTOMREQUEST] in
pop3_perform() where it is then actioned. As I mentioned above, this
function then kicks off the state machine for each command calling the
appropriate doing function (pop3_list(), pop3_uidl(), etc...).

Some of the commands, such as STAT and UIDL (for a single message) return
valuable information in the response. For example STAT might return -OK 10
44764 to indicate that there command was successful and that there are 10
messages in the mailbox with a total size of 44,764 bytes whilst UIDL 5
might return -OK 5 306 to indicate that message 5 has a UID of 306. As such
this information isn't body data so there is no transfer to kick off,
however, the information needs to be passed back to the application as body
data. I'm not 100% happy with how pop3_state_stat_resp() and
pop3_state_uidl_single_resp() handle this but it seems like the best
solution with my limited knowledge of libcurl. If there are any other ways
of doing this I would really appreciate the feedback.

The TOP command also expects two arguments - the message id and the number
of rows. This can be 0 (header only) or a number up to the length of the
message. EG TOP 5 20 will return the header and 20 rows of the message for
message 5. I have added support for rows through the URLs query parameter.
This means I have had to remove the PROTOPT_NOURLQUERY options from the POP3
and POP3S handlers. As it is the only query parameter I haven't given it a
name and it can simple be specified in the following command line to curl:
--url pop3:// -X TOP. If the -X TOP wasn't specified
then curl would try to perform a RETR on message 5?20 (as the query would be
passed straight through) and the server would then return -ERR in its

Note: Whilst I have talked about a mailbox being the box for which mail is
stored in for the connected user, the pop3c struct variable mailbox is used
to store the ID of the Message as specified by the application program in
the URL (This hasn't changed) however, it is really confusing to have the
variable called mailbox as it refers to what we all know as a Message ID
(Not to be confused with a Unique ID which may be obtained through the UIDL
command). As such we might want to consider renaming this variable at some
point in the future to be more meaningful ;-)

Daniel: Whilst I have updated the doc, how do you want to handle test cases
for these commands? I can supply expected results for each of the commands
but still haven't had time to get the test cases up and running under

Kind Regards


Received on 2011-12-10