struct cmd_append_context {
struct client *client;
struct client_command_context *cmd;
- struct mail_storage *storage;
struct mailbox *box;
struct mailbox_transaction_context *t;
time_t started;
/* catenate URL */
ret = imap_msgpart_url_read_part(mpurl, &mpresult, &error);
if (ret < 0) {
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
return -1;
}
if (ret == 0) {
"read(%s) failed: %s (for CATENATE URL %s)",
i_stream_get_name(mpresult.input),
i_stream_get_error(mpresult.input), caturl);
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ret = -1;
} else if (!mpresult.input->eof) {
/* save failed */
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ret = -1;
} else {
/* all the input must be consumed, so istream-chain's read()
ret = imap_msgpart_url_parse(cmd->client->user, cmd->client->mailbox,
caturl, &mpurl, &error);
if (ret < 0) {
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
return -1;
}
if (ret == 0) {
mailbox_save_cancel(&ctx->save_ctx);
} else {
if (mailbox_save_finish(&ctx->save_ctx) < 0) {
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ctx->failed = TRUE;
}
}
else if (mailbox_keywords_create(ctx->box, keywords_list,
&keywords) < 0) {
/* invalid keywords - delay failure */
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ctx->failed = TRUE;
}
}
internal_date, timezone_offset);
if (mailbox_save_begin(&ctx->save_ctx, ctx->input) < 0) {
/* save initialization failed */
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ctx->failed = TRUE;
}
}
ret = mailbox_transaction_commit_get_changes(&ctx->t, &changes);
if (ret < 0) {
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
cmd_append_finish(ctx);
return TRUE;
}
mailbox_save_cancel(&ctx->save_ctx);
} else if (ctx->save_ctx == NULL) {
/* failed above */
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ctx->failed = TRUE;
} else if (lit_offset != ctx->literal_size) {
/* client disconnected before it finished sending the
} else if (ctx->catenate) {
/* CATENATE isn't finished yet */
} else if (mailbox_save_finish(&ctx->save_ctx) < 0) {
- client_send_storage_error(cmd, ctx->storage);
+ client_send_box_error(cmd, ctx->box);
ctx->failed = TRUE;
}
if (client_open_save_dest_box(cmd, mailbox, &ctx->box) < 0)
ctx->failed = TRUE;
else {
- ctx->storage = mailbox_get_storage(ctx->box);
-
ctx->t = mailbox_transaction_begin(ctx->box,
MAILBOX_TRANSACTION_FLAG_EXTERNAL |
MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
box = mailbox_alloc(ns->list, mailbox, 0);
if (mailbox_create(box, NULL, directory) < 0)
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
else
client_send_tagline(cmd, "OK Create completed.");
mailbox_free(&box);
else {
errstr = mailbox_get_last_error(box, &error);
if (error != MAIL_ERROR_EXISTS)
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
else {
/* mailbox has children */
client_send_tagline(cmd, t_strdup_printf("NO %s", errstr));
if (ret < 0) {
errstr = mailbox_get_last_error(client->mailbox, &error);
if (error != MAIL_ERROR_PERM) {
- client_send_storage_error(cmd,
- mailbox_get_storage(client->mailbox));
+ client_send_box_error(cmd, client->mailbox);
return TRUE;
} else {
return cmd_sync(cmd, 0, IMAP_SYNC_FLAG_SAFE,
ctx->box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_READONLY);
if (mailbox_open(ctx->box) < 0) {
- client_send_storage_error(cmd, mailbox_get_storage(ctx->box));
+ client_send_box_error(cmd, ctx->box);
mailbox_free(&ctx->box);
return TRUE;
}
old_box = mailbox_alloc(old_ns->list, oldname, 0);
new_box = mailbox_alloc(new_ns->list, newname, 0);
if (mailbox_rename(old_box, new_box) < 0)
- client_send_storage_error(cmd, mailbox_get_storage(old_box));
+ client_send_box_error(cmd, old_box);
else
client_send_tagline(cmd, "OK Rename completed.");
mailbox_free(&old_box);
/* open mailbox */
box = mailbox_alloc(ns->list, mailbox, flags);
if (mailbox_open(box) < 0) {
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
mailbox_free(&box);
return TRUE;
}
}
ret = imap_fetch_end(ctx->fetch_ctx);
- if (ret < 0) {
- client_send_storage_error(ctx->cmd,
- mailbox_get_storage(ctx->box));
- }
+ if (ret < 0)
+ client_send_box_error(ctx->cmd, ctx->box);
imap_fetch_free(&ctx->fetch_ctx);
cmd_select_finish(ctx, ret);
return TRUE;
flags |= MAILBOX_FLAG_DROP_RECENT;
ctx->box = mailbox_alloc(ctx->ns->list, mailbox, flags);
if (mailbox_open(ctx->box) < 0) {
- client_send_storage_error(ctx->cmd,
- mailbox_get_storage(ctx->box));
+ client_send_box_error(ctx->cmd, ctx->box);
mailbox_free(&ctx->box);
return -1;
}
ret = mailbox_enable(ctx->box, client->enabled_features);
if (ret < 0 ||
mailbox_sync(ctx->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
- client_send_storage_error(ctx->cmd,
- mailbox_get_storage(ctx->box));
+ client_send_box_error(ctx->cmd, ctx->box);
return -1;
}
mailbox_get_open_status(ctx->box, STATUS_MESSAGES | STATUS_RECENT |
if (ctx->qresync_uid_validity == status.uidvalidity &&
status.uidvalidity != 0) {
if ((ret = select_qresync(ctx)) < 0) {
- client_send_storage_error(ctx->cmd,
- mailbox_get_storage(ctx->box));
+ client_send_box_error(ctx->cmd, ctx->box);
return -1;
}
} else {
if (ret < 0 || ctx->cmd_error_sent)
/* already sent the error to client */ ;
else if (ctx->storage_failure)
- client_send_storage_error(cmd, mailbox_get_storage(ctx->box));
+ client_send_box_error(cmd, ctx->box);
else if (mailbox_transaction_commit(&ctx->trans) < 0)
- client_send_storage_error(cmd, mailbox_get_storage(ctx->box));
+ client_send_box_error(cmd, ctx->box);
else
client_send_tagline(cmd, "OK Setmetadata completed.");
cmd_setmetadata_deinit(ctx);
else {
ctx->box = mailbox_alloc(ns->list, mailbox, 0);
if (mailbox_open(ctx->box) < 0) {
- client_send_storage_error(cmd,
- mailbox_get_storage(ctx->box));
+ client_send_box_error(cmd, ctx->box);
mailbox_free(&ctx->box);
return TRUE;
}
if (mailbox_keywords_create(cmd->client->mailbox, keywords_list,
&ctx->keywords) < 0) {
/* invalid keywords */
- client_send_storage_error(cmd,
- mailbox_get_storage(cmd->client->mailbox));
+ client_send_box_error(cmd, cmd->client->mailbox);
return FALSE;
}
}
ret = mailbox_transaction_commit(&t);
if (ret < 0) {
array_free(&modified_set);
- client_send_storage_error(cmd,
- mailbox_get_storage(client->mailbox));
+ client_send_box_error(cmd, client->mailbox);
return TRUE;
}
int ret;
if ((ret = mailbox_exists(box, TRUE, &existence)) < 0) {
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
return FALSE;
}
if (existence == MAILBOX_EXISTENCE_NONE) {
if (mailbox_set_subscribed(box, subscribe) < 0 &&
!unsubscribed_mailbox2) {
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
} else {
client_send_tagline(cmd, subscribe ?
"OK Subscribe completed." :
ret = imap_thread_orderedsubject(cmd, sargs);
mail_search_args_unref(&sargs);
if (ret < 0) {
- client_send_storage_error(cmd,
- mailbox_get_storage(client->mailbox));
+ client_send_box_error(cmd, client->mailbox);
return TRUE;
}
client_send_tagline(cmd, t_strdup_printf(
"NO [TRYCREATE] %s", error_string));
} else {
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
}
mailbox_free(&box);
return -1;
}
if (cmd->client->enabled_features != 0) {
if (mailbox_enable(box, cmd->client->enabled_features) < 0) {
- client_send_storage_error(cmd, mailbox_get_storage(box));
+ client_send_box_error(cmd, box);
mailbox_free(&box);
return -1;
}
error));
}
+void client_send_box_error(struct client_command_context *cmd,
+ struct mailbox *box)
+{
+ if (mailbox_is_inconsistent(box)) {
+ /* we can't do forced CLOSE, so have to disconnect */
+ client_disconnect_with_error(cmd->client,
+ "IMAP session state is inconsistent, please relogin.");
+ return;
+ }
+ client_send_storage_error(cmd, mailbox_get_storage(box));
+}
+
void client_send_storage_error(struct client_command_context *cmd,
struct mail_storage *storage)
{
/* Send last mail storage error message to client. */
void client_send_storage_error(struct client_command_context *cmd,
struct mail_storage *storage);
+/* Send last mailbox's storage error message to client. */
+void client_send_box_error(struct client_command_context *cmd,
+ struct mailbox *box);
/* Send untagged error message to client. */
void client_send_untagged_storage_error(struct client *client,
lost_data = mailbox_search_seen_lost_data(ctx->search_ctx);
if (imap_search_deinit(ctx) < 0) {
- client_send_storage_error(cmd,
- mailbox_get_storage(cmd->client->mailbox));
+ client_send_box_error(cmd, cmd->client->mailbox);
return TRUE;
}