[dovecot-cvs] dovecot/src/imap cmd-append.c,1.80.2.5,1.80.2.6
tss at dovecot.org
tss at dovecot.org
Sun Mar 11 18:02:22 EET 2007
Update of /var/lib/cvs/dovecot/src/imap
In directory talvi:/tmp/cvs-serv4380
Modified Files:
Tag: branch_1_0
cmd-append.c
Log Message:
When using MULTIAPPEND and LITERAL+ and message saving failed, we stopped
parsing client input too early (for subsequent appends after the failure)
which caused BAD replies.
Index: cmd-append.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-append.c,v
retrieving revision 1.80.2.5
retrieving revision 1.80.2.6
diff -u -d -r1.80.2.5 -r1.80.2.6
--- cmd-append.c 1 Mar 2007 11:15:23 -0000 1.80.2.5
+++ cmd-append.c 11 Mar 2007 16:02:20 -0000 1.80.2.6
@@ -24,11 +24,14 @@
struct imap_parser *save_parser;
struct mail_save_context *save_ctx;
- struct mailbox_keywords old_keywords;
+ struct mailbox_keywords old_keywords;
+
+ unsigned int failed:1;
};
static void cmd_append_finish(struct cmd_append_context *ctx);
static bool cmd_append_continue_message(struct client_command_context *cmd);
+static bool cmd_append_continue_parsing(struct client_command_context *cmd);
static void client_input(void *context)
{
@@ -148,11 +151,23 @@
(void)i_stream_get_data(ctx->input, &size);
i_stream_skip(ctx->input, size);
- if (ctx->input->v_offset == ctx->msg_size ||
- cmd->client->input->closed) {
+ if (cmd->client->input->closed) {
cmd_append_finish(ctx);
return TRUE;
}
+
+ if (ctx->input->v_offset == ctx->msg_size) {
+ /* finished, but with MULTIAPPEND and LITERAL+ we may get
+ more messages. */
+ i_stream_unref(&ctx->input);
+ ctx->input = NULL;
+
+ cmd->client->command_pending = FALSE;
+ imap_parser_reset(ctx->save_parser);
+ cmd->func = cmd_append_continue_parsing;
+ return cmd_append_continue_parsing(cmd);
+ }
+
return FALSE;
}
@@ -196,7 +211,7 @@
ret = imap_parser_read_args(ctx->save_parser, 0,
IMAP_PARSE_FLAG_LITERAL_SIZE, &args);
if (ret == -1) {
- if (ctx->box != NULL)
+ if (!ctx->failed)
client_send_command_error(cmd, NULL);
cmd_append_finish(ctx);
return TRUE;
@@ -213,7 +228,7 @@
/* eat away the trailing CRLF */
client->input_skip_line = TRUE;
- if (ctx->box == NULL) {
+ if (ctx->failed) {
/* we failed earlier, error message is sent */
cmd_append_finish(ctx);
return TRUE;
@@ -239,7 +254,7 @@
return cmd_append_cancel(ctx, nonsync);
}
- if (ctx->box == NULL) {
+ if (ctx->failed) {
/* we failed earlier, make sure we just eat nonsync-literal
if it's given. */
return cmd_append_cancel(ctx, nonsync);
@@ -309,7 +324,6 @@
struct client *client = cmd->client;
struct cmd_append_context *ctx = cmd->context;
size_t size;
- bool failed;
int ret;
if (ctx->save_ctx != NULL) {
@@ -342,21 +356,19 @@
if (ctx->save_ctx == NULL) {
/* failed above */
client_send_storage_error(cmd, ctx->storage);
- failed = TRUE;
+ ctx->failed = TRUE;
} else if (!all_written) {
/* client disconnected before it finished sending the
whole message. */
- failed = TRUE;
+ ctx->failed = TRUE;
mailbox_save_cancel(&ctx->save_ctx);
} else if (mailbox_save_finish(&ctx->save_ctx, NULL) < 0) {
- failed = TRUE;
+ ctx->failed = TRUE;
client_send_storage_error(cmd, ctx->storage);
- } else {
- failed = client->input->closed;
}
ctx->save_ctx = NULL;
- if (failed) {
+ if (client->input->closed) {
cmd_append_finish(ctx);
return TRUE;
}
@@ -435,12 +447,15 @@
ctx->cmd = cmd;
ctx->client = client;
ctx->box = get_mailbox(cmd, mailbox);
- if (ctx->box != NULL) {
+ if (ctx->box == NULL)
+ ctx->failed = TRUE;
+ else {
ctx->storage = mailbox_get_storage(ctx->box);
if (get_keywords(ctx) < 0) {
client_send_storage_error(cmd, ctx->storage);
mailbox_close(&ctx->box);
+ ctx->failed = TRUE;
} else {
ctx->t = mailbox_transaction_begin(ctx->box,
MAILBOX_TRANSACTION_FLAG_EXTERNAL);
More information about the dovecot-cvs
mailing list