dovecot-2.2: imap: FETCH API cleanup: keep fetch state in a sepa...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 13 02:38:58 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/0c73a42c194e
changeset: 14887:0c73a42c194e
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 13 01:47:54 2012 +0300
description:
imap: FETCH API cleanup: keep fetch state in a separate struct.
diffstat:
src/imap/cmd-fetch.c | 11 +-
src/imap/imap-fetch-body.c | 93 ++++++++++++----------
src/imap/imap-fetch.c | 187 ++++++++++++++++++++++----------------------
src/imap/imap-fetch.h | 45 ++++++----
4 files changed, 175 insertions(+), 161 deletions(-)
diffs (truncated from 767 to 300 lines):
diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/cmd-fetch.c Mon Aug 13 01:47:54 2012 +0300
@@ -144,19 +144,20 @@
static const char *ok_message = "OK Fetch completed.";
const char *tagged_reply = ok_message;
enum mail_error error;
+ bool seen_flags_changed = ctx->state.seen_flags_changed;
- if (ctx->skipped_expunged_msgs) {
+ if (ctx->state.skipped_expunged_msgs) {
tagged_reply = "OK ["IMAP_RESP_CODE_EXPUNGEISSUED"] "
"Some messages were already expunged.";
}
if (imap_fetch_deinit(ctx) < 0)
- ctx->failed = TRUE;
+ ctx->state.failed = TRUE;
- if (ctx->failed) {
+ if (ctx->state.failed) {
const char *errstr;
- if (ctx->client->output->closed) {
+ if (cmd->client->output->closed) {
client_disconnect(cmd->client, "Disconnected");
return TRUE;
}
@@ -175,7 +176,7 @@
}
return cmd_sync(cmd,
- (ctx->seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) |
+ (seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) |
(cmd->uid ? 0 : MAILBOX_SYNC_FLAG_NO_EXPUNGES), 0,
tagged_reply);
}
diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/imap-fetch-body.c Mon Aug 13 01:47:54 2012 +0300
@@ -30,11 +30,13 @@
static void fetch_read_error(struct imap_fetch_context *ctx)
{
- errno = ctx->cur_input->stream_errno;
+ struct imap_fetch_state *state = &ctx->state;
+
+ errno = state->cur_input->stream_errno;
mail_storage_set_critical(ctx->box->storage,
"read(%s) failed: %m (FETCH for mailbox %s UID %u)",
- i_stream_get_name(ctx->cur_input),
- mailbox_get_vname(ctx->cur_mail->box), ctx->cur_mail->uid);
+ i_stream_get_name(state->cur_input),
+ mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid);
}
static const char *get_body_name(const struct imap_fetch_body_data *body)
@@ -63,8 +65,8 @@
string_t *str;
str = t_str_new(128);
- if (ctx->first)
- ctx->first = FALSE;
+ if (ctx->state.cur_first)
+ ctx->state.cur_first = FALSE;
else
str_append_c(str, ' ');
@@ -81,31 +83,34 @@
static int fetch_stream_continue(struct imap_fetch_context *ctx)
{
+ struct imap_fetch_state *state = &ctx->state;
off_t ret;
o_stream_set_max_buffer_size(ctx->client->output, 0);
- ret = o_stream_send_istream(ctx->client->output, ctx->cur_input);
+ ret = o_stream_send_istream(ctx->client->output, state->cur_input);
o_stream_set_max_buffer_size(ctx->client->output, (size_t)-1);
if (ret > 0)
- ctx->cur_offset += ret;
+ state->cur_offset += ret;
- if (ctx->cur_offset != ctx->cur_size) {
+ if (state->cur_offset != state->cur_size) {
/* unfinished */
- if (ctx->cur_input->stream_errno != 0) {
+ if (state->cur_input->stream_errno != 0) {
fetch_read_error(ctx);
client_disconnect(ctx->client, "FETCH failed");
return -1;
}
- if (!i_stream_have_bytes_left(ctx->cur_input)) {
+ if (!i_stream_have_bytes_left(state->cur_input)) {
/* Input stream gave less data than expected */
i_error("FETCH %s for mailbox %s UID %u "
"got too little data: "
"%"PRIuUOFF_T" vs %"PRIuUOFF_T,
- ctx->cur_name, mailbox_get_vname(ctx->cur_mail->box),
- ctx->cur_mail->uid, ctx->cur_offset, ctx->cur_size);
- mail_set_cache_corrupted(ctx->cur_mail,
- ctx->cur_size_field);
+ state->cur_human_name,
+ mailbox_get_vname(state->cur_mail->box),
+ state->cur_mail->uid,
+ state->cur_offset, state->cur_size);
+ mail_set_cache_corrupted(state->cur_mail,
+ state->cur_size_field);
client_disconnect(ctx->client, "FETCH failed");
return -1;
}
@@ -128,17 +133,18 @@
if (imap_msgpart_open(mail, body->msgpart, &result) < 0)
return -1;
- ctx->cur_input = result.input;
- ctx->cur_size = result.size;
- ctx->cur_size_field = result.size_field;
- ctx->cur_name = p_strconcat(ctx->pool, "[", body->section, "]", NULL);
+ ctx->state.cur_input = result.input;
+ ctx->state.cur_size = result.size;
+ ctx->state.cur_size_field = result.size_field;
+ ctx->state.cur_human_name =
+ p_strconcat(ctx->pool, "[", body->section, "]", NULL);
- str = get_prefix(ctx, body, ctx->cur_size,
+ str = get_prefix(ctx, body, ctx->state.cur_size,
result.binary_decoded_input_has_nuls);
o_stream_nsend(ctx->client->output, str_data(str), str_len(str));
- ctx->cont_handler = fetch_stream_continue;
- return ctx->cont_handler(ctx);
+ ctx->state.cont_handler = fetch_stream_continue;
+ return ctx->state.cont_handler(ctx);
}
static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail,
@@ -151,8 +157,8 @@
return -1;
str = t_str_new(128);
- if (ctx->first)
- ctx->first = FALSE;
+ if (ctx->state.cur_first)
+ ctx->state.cur_first = FALSE;
else
str_append_c(str, ' ');
str_printfa(str, "%s %"PRIuUOFF_T, get_body_name(body), size);
@@ -412,7 +418,7 @@
if (mail_get_virtual_size(mail, &size) < 0)
return -1;
- str_printfa(ctx->cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
+ str_printfa(ctx->state.cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
return 1;
}
@@ -427,10 +433,10 @@
imap_msgpart_free(_msgpart);
if (ret < 0)
return -1;
- ctx->cur_input = result.input;
- ctx->cur_size = result.size;
- ctx->cur_size_field = result.size_field;
- ctx->cont_handler = fetch_stream_continue;
+ ctx->state.cur_input = result.input;
+ ctx->state.cur_size = result.size;
+ ctx->state.cur_size_field = result.size_field;
+ ctx->state.cont_handler = fetch_stream_continue;
return 0;
}
@@ -445,14 +451,15 @@
if (fetch_and_free_msgpart(ctx, mail, &msgpart) < 0)
return -1;
- str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n", ctx->cur_size);
- if (ctx->first) {
- str++; ctx->first = FALSE;
+ str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n",
+ ctx->state.cur_size);
+ if (ctx->state.cur_first) {
+ str++; ctx->state.cur_first = FALSE;
}
o_stream_nsend_str(ctx->client->output, str);
- ctx->cur_name = "RFC822";
- return ctx->cont_handler(ctx);
+ ctx->state.cur_human_name = "RFC822";
+ return ctx->state.cont_handler(ctx);
}
static int ATTR_NULL(3)
@@ -467,14 +474,14 @@
return -1;
str = t_strdup_printf(" RFC822.HEADER {%"PRIuUOFF_T"}\r\n",
- ctx->cur_size);
- if (ctx->first) {
- str++; ctx->first = FALSE;
+ ctx->state.cur_size);
+ if (ctx->state.cur_first) {
+ str++; ctx->state.cur_first = FALSE;
}
o_stream_nsend_str(ctx->client->output, str);
- ctx->cur_name = "RFC822.HEADER";
- return ctx->cont_handler(ctx);
+ ctx->state.cur_human_name = "RFC822.HEADER";
+ return ctx->state.cont_handler(ctx);
}
static int ATTR_NULL(3)
@@ -489,14 +496,14 @@
return -1;
str = t_strdup_printf(" RFC822.TEXT {%"PRIuUOFF_T"}\r\n",
- ctx->cur_size);
- if (ctx->first) {
- str++; ctx->first = FALSE;
+ ctx->state.cur_size);
+ if (ctx->state.cur_first) {
+ str++; ctx->state.cur_first = FALSE;
}
o_stream_nsend_str(ctx->client->output, str);
- ctx->cur_name = "RFC822.TEXT";
- return ctx->cont_handler(ctx);
+ ctx->state.cur_human_name = "RFC822.TEXT";
+ return ctx->state.cont_handler(ctx);
}
bool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx)
diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch.c
--- a/src/imap/imap-fetch.c Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/imap-fetch.c Mon Aug 13 01:47:54 2012 +0300
@@ -105,12 +105,12 @@
ctx->pool = cmd->pool;
ctx->box = box;
- ctx->cur_str = str_new(default_pool, 8192);
+ ctx->state.cur_str = str_new(default_pool, 8192);
p_array_init(&ctx->all_headers, cmd->pool, 64);
p_array_init(&ctx->handlers, cmd->pool, 16);
p_array_init(&ctx->tmp_keywords, cmd->pool,
client->keywords.announce_count + 8);
- ctx->line_finished = TRUE;
+ ctx->state.line_finished = TRUE;
return ctx;
}
@@ -140,8 +140,8 @@
/* partially because of broken clients, but also partially because
it potentially can make client implementations faster, we have a
buffered parameter which basically means that the handler promises
- to write the output in fetch_ctx->cur_str. The cur_str is then sent
- to client before calling any non-buffered handlers.
+ to write the output in fetch_ctx->state.cur_str. The cur_str is then
+ sent to client before calling any non-buffered handlers.
We try to keep the handler registration order the same as the
client requested them. This is especially useful to get UID
@@ -327,11 +327,12 @@
int imap_fetch_begin(struct imap_fetch_context *ctx)
{
+ struct mailbox_header_lookup_ctx *wanted_headers = NULL;
const void *data;
if (ctx->send_vanished) {
if (imap_fetch_send_vanished(ctx) < 0) {
- ctx->failed = TRUE;
+ ctx->state.failed = TRUE;
return -1;
}
}
@@ -351,24 +352,25 @@
array_append_zero(&ctx->all_headers);
data = array_idx(&ctx->all_headers, 0);
- ctx->all_headers_ctx =
- mailbox_header_lookup_init(ctx->box, data);
+ wanted_headers = mailbox_header_lookup_init(ctx->box, data);
}
if ((ctx->fetch_data &
(MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0)
ctx->fetch_data |= MAIL_FETCH_NUL_STATE;
- ctx->trans = mailbox_transaction_begin(ctx->box,
+ ctx->state.trans = mailbox_transaction_begin(ctx->box,
MAILBOX_TRANSACTION_FLAG_HIDE |
MAILBOX_TRANSACTION_FLAG_REFRESH);
/* Delayed uidset -> seqset conversion. VANISHED needs the uidset. */
mail_search_args_init(ctx->search_args, ctx->box, TRUE,
&ctx->client->search_saved_uidset);
- ctx->search_ctx =
- mailbox_search_init(ctx->trans, ctx->search_args, NULL,
More information about the dovecot-cvs
mailing list