Hello, it has been reported to this list earlier that moving messages from local mailboxes into DBMail using IMAP does not work properly (even when not using Evolution ;-). I can confirm this problem and I have found the cause for that.
The function _ic_append() in imapcommands.c reads a literal string (the message to be appended to the mailbox) from the client (the size is given as the last argument on the command line of the APPEND command and passed to _ic_append()). Regarding literal strings RFC2060 states (section 7.5, third paragraph): [...] The remainder of the command, including the CRLF that terminates a command, follows the octets of the literal. If there are any additional command arguments the literal octets are followed by a space and those arguments. Note that the rest of the command (including CRLF) is following the literal string, i.e. the literal string is _not_ the end of the command. The literal string argument to APPEND is the last argument, so a CRLF has to follow it. _ic_append() does not take care of reading this CRLF, so the next iteration of the command loop reads an empty line, which in turn increments `nfaultyresponses' and terminates the IMAP connection after MAX_FAULTY_RESPONSES (i.e. 5) APPEND commands. I have attached a patch which fixes this by reading the CRLF in _ic_append() (or returning an error if no CRLF is read). I think that the "real" solution should be different: If I interpret RCF2060 correctly then literal strings can be used in a lot of places instead of quoted strings, e.g. for mailbox names, user names or passwords ("astring" in the grammer in section 9 of RFC2060). I suggest therefore to rewrite the command parsing code to handle literal strings in the command parser, not in e.g. _ic_append(). It is probably too late for that change before 1.0, but some sort of fix for the APPEND command should go in. I hope this helps to improve DBMail. Regards, Armin
--- dbmail/imapcommands.c 2002-11-12 18:56:18.000000000 +0100 +++ dbmail.append-crlf/imapcommands.c 2002-11-12 18:59:25.000000000 +0100 @@ -1450,30 +1450,45 @@ msgdata[dataidx] = 0; /* terminate (safety, this byte will not be stored) */ + /* the literal string MUST be followed by CRLF */ + result = 0; + if (fgetc(ci->rx) != '\r') + result = 1; + else if (fgetc(ci->rx) != '\n') + result = 1; + alarm(0); /* clear alarm */ - /* insert this msg */ - result = db_imap_append_msg(msgdata, dataidx, mboxid, ud->userid); - switch (result) - { - case -1: - trace(TRACE_ERROR,"ic_append(): error appending msg\n"); - fprintf(ci->tx,"* BYE internal dbase error storing message\r\n"); - break; - - case 1: - trace(TRACE_ERROR,"ic_append(): faulty msg\n"); - fprintf(ci->tx,"%s NO invalid message specified\r\n", tag); - break; - - case 2: - trace(TRACE_INFO,"ic_append(): quotum would exceed\n"); - fprintf(ci->tx,"%s NO not enough quotum left\r\n", tag); - break; - - case 0: - fprintf(ci->tx,"%s OK APPEND completed\r\n",tag); - break; + if (result != 0) + { + trace(TRACE_ERROR,"ic_append(): msg followed by CRLF\n"); + fprintf(ci->tx,"%s BAD expected crlf after literal string\r\n", tag); + } + else + { + /* insert this msg */ + result = db_imap_append_msg(msgdata, dataidx, mboxid, ud->userid); + switch (result) + { + case -1: + trace(TRACE_ERROR,"ic_append(): error appending msg\n"); + fprintf(ci->tx,"* BYE internal dbase error storing message\r\n"); + break; + + case 1: + trace(TRACE_ERROR,"ic_append(): faulty msg\n"); + fprintf(ci->tx,"%s NO invalid message specified\r\n", tag); + break; + + case 2: + trace(TRACE_INFO,"ic_append(): quotum would exceed\n"); + fprintf(ci->tx,"%s NO not enough quotum left\r\n", tag); + break; + + case 0: + fprintf(ci->tx,"%s OK APPEND completed\r\n",tag); + break; + } } my_free(msgdata);