dovecot-2.2: imap: FETCH API updated to allow using the same par...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 13 02:51:20 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/00be97a2139a
changeset: 14889:00be97a2139a
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 13 02:51:09 2012 +0300
description:
imap: FETCH API updated to allow using the same parsed FETCH in multiple mailboxes.
This is in preparation for NOTIFY extension.
diffstat:
src/imap/cmd-fetch.c | 79 +++++++++++-----
src/imap/cmd-select.c | 41 +++++---
src/imap/imap-fetch-body.c | 33 +++---
src/imap/imap-fetch.c | 216 ++++++++++++++++++++++++++------------------
src/imap/imap-fetch.h | 38 +++++--
5 files changed, 246 insertions(+), 161 deletions(-)
diffs (truncated from 858 to 300 lines):
diff -r cf79ab812651 -r 00be97a2139a src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c Mon Aug 13 02:41:08 2012 +0300
+++ b/src/imap/cmd-fetch.c Mon Aug 13 02:51:09 2012 +0300
@@ -21,6 +21,28 @@
};
static bool
+imap_fetch_cmd_init_handler(struct imap_fetch_context *ctx,
+ struct client_command_context *cmd,
+ const char *name, const struct imap_arg **args)
+{
+ struct imap_fetch_init_context init_ctx;
+
+ memset(&init_ctx, 0, sizeof(init_ctx));
+ init_ctx.fetch_ctx = ctx;
+ init_ctx.pool = ctx->ctx_pool;
+ init_ctx.name = name;
+ init_ctx.args = *args;
+
+ if (!imap_fetch_init_handler(&init_ctx)) {
+ i_assert(init_ctx.error != NULL);
+ client_send_command_error(cmd, init_ctx.error);
+ return FALSE;
+ }
+ *args = init_ctx.args;
+ return TRUE;
+}
+
+static bool
fetch_parse_args(struct imap_fetch_context *ctx,
struct client_command_context *cmd,
const struct imap_arg *arg, const struct imap_arg **next_arg_r)
@@ -81,7 +103,8 @@
static bool
fetch_parse_modifier(struct imap_fetch_context *ctx,
struct client_command_context *cmd,
- const char *name, const struct imap_arg **args)
+ const char *name, const struct imap_arg **args,
+ bool *send_vanished)
{
const char *str;
uint64_t modseq;
@@ -103,7 +126,7 @@
client_send_command_error(cmd, "QRESYNC not enabled");
return FALSE;
}
- ctx->send_vanished = TRUE;
+ *send_vanished = TRUE;
return TRUE;
}
@@ -114,10 +137,12 @@
static bool
fetch_parse_modifiers(struct imap_fetch_context *ctx,
struct client_command_context *cmd,
- const struct imap_arg *args)
+ const struct imap_arg *args, bool *send_vanished_r)
{
const char *name;
+ *send_vanished_r = FALSE;
+
while (!IMAP_ARG_IS_EOL(args)) {
if (!imap_arg_get_atom(args, &name)) {
client_send_command_error(cmd,
@@ -125,10 +150,11 @@
return FALSE;
}
args++;
- if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name), &args))
+ if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name),
+ &args, send_vanished_r))
return FALSE;
}
- if (ctx->send_vanished &&
+ if (*send_vanished_r &&
(ctx->search_args->args->next == NULL ||
ctx->search_args->args->next->type != SEARCH_MODSEQ)) {
client_send_command_error(cmd,
@@ -144,17 +170,17 @@
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;
+ bool failed, seen_flags_changed = ctx->state.seen_flags_changed;
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->state.failed = TRUE;
+ failed = imap_fetch_end(ctx) < 0;
+ imap_fetch_free(&ctx);
- if (ctx->state.failed) {
+ if (failed) {
const char *errstr;
if (cmd->client->output->closed) {
@@ -198,7 +224,9 @@
struct imap_fetch_context *ctx;
const struct imap_arg *args, *next_arg, *list_arg;
struct mail_search_args *search_args;
+ struct imap_fetch_qresync_args qresync_args;
const char *messageset;
+ bool send_vanished = FALSE;
int ret;
if (!client_read_args(cmd, 0, 0, &args))
@@ -221,29 +249,32 @@
if (ret <= 0)
return ret < 0;
- ctx = imap_fetch_init(cmd, client->mailbox);
- if (ctx == NULL) {
- mail_search_args_unref(&search_args);
- return TRUE;
- }
+ ctx = imap_fetch_alloc(client, cmd->pool);
ctx->search_args = search_args;
if (!fetch_parse_args(ctx, cmd, &args[1], &next_arg) ||
(imap_arg_get_list(next_arg, &list_arg) &&
- !fetch_parse_modifiers(ctx, cmd, list_arg))) {
- (void)imap_fetch_deinit(ctx);
+ !fetch_parse_modifiers(ctx, cmd, list_arg, &send_vanished))) {
+ imap_fetch_free(&ctx);
return TRUE;
}
- if (imap_fetch_begin(ctx) == 0) {
- if (imap_fetch_more(ctx, cmd) == 0) {
- /* unfinished */
- cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
+ if (send_vanished) {
+ memset(&qresync_args, 0, sizeof(qresync_args));
+ if (imap_fetch_send_vanished(client, client->mailbox,
+ search_args, &qresync_args) < 0)
+ return cmd_fetch_finish(ctx, cmd);
+ }
- cmd->func = cmd_fetch_continue;
- cmd->context = ctx;
- return FALSE;
- }
+ imap_fetch_begin_once(ctx, client->mailbox);
+
+ if (imap_fetch_more(ctx, cmd) == 0) {
+ /* unfinished */
+ cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
+
+ cmd->func = cmd_fetch_continue;
+ cmd->context = ctx;
+ return FALSE;
}
return cmd_fetch_finish(ctx, cmd);
}
diff -r cf79ab812651 -r 00be97a2139a src/imap/cmd-select.c
--- a/src/imap/cmd-select.c Mon Aug 13 02:41:08 2012 +0300
+++ b/src/imap/cmd-select.c Mon Aug 13 02:51:09 2012 +0300
@@ -219,11 +219,12 @@
return FALSE;
}
- ret = imap_fetch_deinit(ctx->fetch_ctx);
+ ret = imap_fetch_end(ctx->fetch_ctx);
if (ret < 0) {
client_send_storage_error(ctx->cmd,
mailbox_get_storage(ctx->box));
}
+ imap_fetch_free(&ctx->fetch_ctx);
cmd_select_finish(ctx, ret);
return TRUE;
}
@@ -232,39 +233,45 @@
{
struct imap_fetch_context *fetch_ctx;
struct mail_search_args *search_args;
+ struct imap_fetch_qresync_args qresync_args;
search_args = mail_search_build_init();
search_args->args = p_new(search_args->pool, struct mail_search_arg, 1);
search_args->args->type = SEARCH_UIDSET;
search_args->args->value.seqset = ctx->qresync_known_uids;
- fetch_ctx = imap_fetch_init(ctx->cmd, ctx->box);
- if (fetch_ctx == NULL)
+ memset(&qresync_args, 0, sizeof(qresync_args));
+ qresync_args.qresync_sample_seqset = &ctx->qresync_sample_seqset;
+ qresync_args.qresync_sample_uidset = &ctx->qresync_sample_uidset;
+
+ if (imap_fetch_send_vanished(ctx->cmd->client, ctx->box,
+ search_args, &qresync_args) < 0) {
+ mail_search_args_unref(&search_args);
return -1;
+ }
+ fetch_ctx = imap_fetch_alloc(ctx->cmd->client, ctx->cmd->pool);
fetch_ctx->search_args = search_args;
- fetch_ctx->send_vanished = TRUE;
- fetch_ctx->qresync_sample_seqset = &ctx->qresync_sample_seqset;
- fetch_ctx->qresync_sample_uidset = &ctx->qresync_sample_uidset;
imap_fetch_add_changed_since(fetch_ctx, ctx->qresync_modseq);
imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_uid_init);
imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_flags_init);
imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_modseq_init);
- if (imap_fetch_begin(fetch_ctx) == 0) {
- if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) {
- /* unfinished */
- ctx->fetch_ctx = fetch_ctx;
- ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
+ imap_fetch_begin_once(fetch_ctx, ctx->box);
+ if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) {
+ /* unfinished */
+ ctx->fetch_ctx = fetch_ctx;
+ ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
- ctx->cmd->func = cmd_select_continue;
- ctx->cmd->context = ctx;
- return 0;
- }
+ ctx->cmd->func = cmd_select_continue;
+ ctx->cmd->context = ctx;
+ return 0;
}
-
- return imap_fetch_deinit(fetch_ctx) < 0 ? -1 : 1;
+ if (imap_fetch_end(fetch_ctx) < 0)
+ return -1;
+ imap_fetch_free(&fetch_ctx);
+ return 1;
}
static int
diff -r cf79ab812651 -r 00be97a2139a src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c Mon Aug 13 02:41:08 2012 +0300
+++ b/src/imap/imap-fetch-body.c Mon Aug 13 02:51:09 2012 +0300
@@ -33,7 +33,7 @@
struct imap_fetch_state *state = &ctx->state;
errno = state->cur_input->stream_errno;
- mail_storage_set_critical(ctx->box->storage,
+ mail_storage_set_critical(state->cur_mail->box->storage,
"read(%s) failed: %m (FETCH for mailbox %s UID %u)",
i_stream_get_name(state->cur_input),
mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid);
@@ -58,15 +58,15 @@
return str_c(str);
}
-static string_t *get_prefix(struct imap_fetch_context *ctx,
+static string_t *get_prefix(struct imap_fetch_state *state,
const struct imap_fetch_body_data *body,
uoff_t size, bool has_nuls)
{
string_t *str;
str = t_str_new(128);
- if (ctx->state.cur_first)
- ctx->state.cur_first = FALSE;
+ if (state->cur_first)
+ state->cur_first = FALSE;
else
str_append_c(str, ' ');
@@ -136,10 +136,9 @@
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);
+ ctx->state.cur_human_name = body->section;
- str = get_prefix(ctx, body, ctx->state.cur_size,
+ str = get_prefix(&ctx->state, body, ctx->state.cur_size,
result.binary_decoded_input_has_nuls);
o_stream_nsend(ctx->client->output, str_data(str), str_len(str));
@@ -196,7 +195,7 @@
const char *value;
size_t i;
- str = str_new(ctx->fetch_ctx->pool, 128);
+ str = str_new(ctx->pool, 128);
str_append(str, prefix);
str_append(str, " (");
@@ -277,7 +276,7 @@
i_assert(strncmp(ctx->name, "BODY", 4) == 0);
p = ctx->name + 4;
- body = p_new(ctx->fetch_ctx->pool, struct imap_fetch_body_data, 1);
+ body = p_new(ctx->pool, struct imap_fetch_body_data, 1);
if (strncmp(p, ".PEEK", 5) == 0)
p += 5;
More information about the dovecot-cvs
mailing list