int client_enable(struct client *client, enum mailbox_feature features) { struct mailbox_status status; int ret; if ((client->enabled_features & features) == features) return 0; client->enabled_features |= features; if (client->mailbox == NULL) return 0; ret = mailbox_enable(client->mailbox, features); if ((features & MAILBOX_FEATURE_CONDSTORE) != 0 && ret == 0) { /* CONDSTORE being enabled while mailbox is selected. Notify client of the latest HIGHESTMODSEQ. */ ret = mailbox_get_status(client->mailbox, STATUS_HIGHESTMODSEQ, &status); if (ret == 0) { client_send_line(client, t_strdup_printf( "* OK [HIGHESTMODSEQ %llu] Highest", (unsigned long long)status.highest_modseq)); } } if (ret < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); } return ret; }
bool cmd_close(struct client_command_context *cmd) { struct client *client = cmd->client; struct mailbox *mailbox = client->mailbox; struct mail_storage *storage; if (!client_verify_open_mailbox(cmd)) return TRUE; i_assert(client->mailbox_change_lock == NULL); client->mailbox = NULL; storage = mailbox_get_storage(mailbox); if (imap_expunge(mailbox, NULL) < 0) client_send_untagged_storage_error(client, storage); if (mailbox_sync(mailbox, 0) < 0) client_send_untagged_storage_error(client, storage); mailbox_free(&mailbox); client_update_mailbox_flags(client, NULL); client_send_tagline(cmd, "OK Close completed."); return TRUE; }
static bool cmd_idle_continue(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_idle_context *ctx = cmd->context; uoff_t orig_offset = client->output->offset; if (cmd->cancel) { idle_finish(ctx, FALSE, FALSE); return TRUE; } if (ctx->manual_cork) { /* we're coming from idle_callback instead of a normal I/O handler, so we'll have to do corking manually */ o_stream_cork(client->output); } if (ctx->sync_ctx != NULL) { if (imap_sync_more(ctx->sync_ctx) == 0) { /* unfinished */ if (ctx->manual_cork) { ctx->manual_cork = FALSE; o_stream_uncork(client->output); } cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; return FALSE; } if (imap_sync_deinit(ctx->sync_ctx, ctx->cmd) < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); mailbox_notify_changes_stop(client->mailbox); } ctx->sync_ctx = NULL; } if (client->output->offset != orig_offset && ctx->keepalive_to != NULL) idle_add_keepalive_timeout(ctx); if (ctx->sync_pending) { /* more changes occurred while we were sending changes to client */ idle_sync_now(client->mailbox, ctx); /* NOTE: this recurses back to this function, so we return here instead of doing everything twice. */ return FALSE; } cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT; if (ctx->manual_cork) { ctx->manual_cork = FALSE; o_stream_uncork(client->output); } if (client->output->closed) { idle_finish(ctx, FALSE, FALSE); return TRUE; } if (client->io == NULL) { /* input is pending */ client->io = io_add(i_stream_get_fd(client->input), IO_READ, idle_client_input, ctx); idle_client_input_more(ctx); } return FALSE; }