cmd-select.c revision 167da1aee2bf5c9cbe7066ff65b406d92df3541c
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainenstatic int select_qresync_get_uids(struct imap_select_context *ctx,
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen /* change all n:m ranges to n,m and store the results */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen i_array_init(&ctx->qresync_sample_uidset, uid_count);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen i_array_init(&ctx->qresync_sample_seqset, uid_count);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen for (i = 0; i < uid_count; i++) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (!seq_range_array_iter_nth(&seq_iter, n++, &seq))
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen array_append(&ctx->qresync_sample_seqset, &seq, 1);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (!seq_range_array_iter_nth(&seq_iter, n++, &seq))
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen array_append(&ctx->qresync_sample_seqset, &seq, 1);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (seq_range_array_iter_nth(&seq_iter, n, &seq))
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenselect_parse_qresync_known_set(struct imap_select_context *ctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const char *str;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen imap_seq_set_nostar_parse(str, &seqset) < 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "Invalid QRESYNC known-sequence-set");
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen imap_seq_set_nostar_parse(str, &uidset) < 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "Invalid QRESYNC known-uid-set");
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (select_qresync_get_uids(ctx, &seqset, &uidset) < 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen client_send_command_error(ctx->cmd, "Invalid QRESYNC sets");
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "Too many parameters to QRESYNC known set");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenselect_parse_qresync(struct imap_select_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *str;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen unsigned int count;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen client_send_command_error(ctx->cmd, "QRESYNC not enabled");
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen if (!imap_arg_get_list_full(args, &args, &count)) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "QRESYNC parameters missing");
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen str_to_uint32(str, &ctx->qresync_uid_validity) < 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_to_uint64(str, &ctx->qresync_modseq) < 0) {
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen "Invalid QRESYNC parameters");
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen if (imap_seq_set_nostar_parse(str, &ctx->qresync_known_uids) < 0) {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen "Invalid QRESYNC known-uids");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_add_range(&ctx->qresync_known_uids,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!select_parse_qresync_known_set(ctx, list_args))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Invalid QRESYNC parameters");
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainenselect_parse_options(struct imap_select_context *ctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "SELECT options contain non-atoms.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Unknown FETCH modifier");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void select_context_free(struct imap_select_context *ctx)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (array_is_created(&ctx->qresync_known_uids))
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (array_is_created(&ctx->qresync_sample_seqset))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (array_is_created(&ctx->qresync_sample_uidset))
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic void cmd_select_finish(struct imap_select_context *ctx, int ret)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen time_msecs = timeval_diff_msecs(&end_time, &ctx->start_time);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen client_send_tagline(ctx->cmd, t_strdup_printf(
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen "OK [%s] %s completed (%d.%03d secs).", resp_code,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->cmd->client->mailbox_examined ? "Examine" : "Select",
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic bool cmd_select_continue(struct client_command_context *cmd)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct imap_select_context *ctx = cmd->context;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (imap_fetch_more(ctx->fetch_ctx, cmd) == 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* unfinished */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic int select_qresync(struct imap_select_context *ctx)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen search_args->args = p_new(search_args->pool, struct mail_search_arg, 1);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen search_args->args->value.seqset = ctx->qresync_known_uids;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen imap_search_add_changed_since(search_args, ctx->qresync_modseq);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen memset(&qresync_args, 0, sizeof(qresync_args));
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen qresync_args.qresync_sample_seqset = &ctx->qresync_sample_seqset;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen qresync_args.qresync_sample_uidset = &ctx->qresync_sample_uidset;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (imap_fetch_send_vanished(ctx->cmd->client, ctx->box,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fetch_ctx = imap_fetch_alloc(ctx->cmd->client, ctx->cmd->pool);
39775ad03c459efe64cce924658da5094ba417e1Timo Sirainen imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_uid_init);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_flags_init);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_modseq_init);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_fetch_begin(fetch_ctx, ctx->box, search_args);
39775ad03c459efe64cce924658da5094ba417e1Timo Sirainen if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) {
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen /* unfinished */
39775ad03c459efe64cce924658da5094ba417e1Timo Sirainen ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainenselect_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->box = mailbox_alloc(ctx->ns->list, mailbox, flags);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ret = mailbox_enable(ctx->box, client->enabled_features);
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainen mailbox_sync(ctx->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mailbox_get_open_status(ctx->box, STATUS_MESSAGES | STATUS_RECENT |
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY |
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen client_update_mailbox_flags(client, status.keywords);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen t_strdup_printf("* %u EXISTS", status.messages));
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen t_strdup_printf("* %u RECENT", status.recent));
return ret;
int ret;
return FALSE;
return FALSE;
return TRUE;
return TRUE;
if (ret == 0)
return FALSE;
return TRUE;