# HG changeset patch # User Timo Sirainen # Date 1198275669 -7200 # Node ID 80d3b8fcec092c2cab8d5ca7a051cf60ae66c63f # Parent ac32dc7ae0c12fa4c6e51f15da8d5a8b41e3c96a When pipelining commands another command could have written output in the middle of FETCH literal. diff -r ac32dc7ae0c1 -r 80d3b8fcec09 src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Fri Dec 21 22:58:11 2007 +0200 +++ b/src/imap/imap-fetch.c Sat Dec 22 00:21:09 2007 +0200 @@ -232,7 +232,7 @@ return 0; } -int imap_fetch(struct imap_fetch_context *ctx) +static int imap_fetch_more(struct imap_fetch_context *ctx) { struct client *client = ctx->client; const struct imap_fetch_context_handler *handlers; @@ -245,7 +245,7 @@ return 0; if (ret < 0) { - if (ctx->client->output->closed) + if (client->output->closed) return -1; if (ctx->cur_mail->expunged) { @@ -265,23 +265,13 @@ i_stream_unref(&ctx->cur_input); } - /* assume initially that we're locking it */ - i_assert(client->output_lock == NULL || - client->output_lock == ctx->cmd); - client->output_lock = ctx->cmd; - handlers = array_get(&ctx->handlers, &count); for (;;) { if (o_stream_get_buffer_used_size(client->output) >= CLIENT_OUTPUT_OPTIMAL_SIZE) { ret = o_stream_flush(client->output); - if (ret <= 0) { - if (!ctx->line_partial) { - /* last line was fully sent */ - client->output_lock = NULL; - } + if (ret <= 0) return ret; - } } if (ctx->cur_mail == NULL) { @@ -317,13 +307,8 @@ h->context); ); - if (ret == 0) { - if (!ctx->line_partial) { - /* last line was fully sent */ - client->output_lock = NULL; - } + if (ret == 0) return 0; - } if (ret < 0) { if (ctx->cur_mail->expunged) { @@ -354,7 +339,7 @@ ctx->line_partial = FALSE; if (o_stream_send(client->output, ")\r\n", 3) < 0) return -1; - ctx->client->last_output = ioloop_time; + client->last_output = ioloop_time; ctx->cur_mail = NULL; ctx->cur_handler = 0; @@ -363,6 +348,21 @@ return 1; } +int imap_fetch(struct imap_fetch_context *ctx) +{ + int ret; + + i_assert(ctx->client->output_lock == NULL || + ctx->client->output_lock == ctx->cmd); + + ret = imap_fetch_more(ctx); + if (ctx->line_partial) { + /* nothing can be sent until FETCH is finished */ + ctx->client->output_lock = ctx->cmd; + } + return ret; +} + int imap_fetch_deinit(struct imap_fetch_context *ctx) { const struct imap_fetch_context_handler *handlers;