const char *storage_name, *error;
storage_name = mail_namespace_get_storage_name(ctx->ns, name);
- if (imap_status_get(ctx->cmd->client, ctx->ns, storage_name,
+ if (imap_status_get(ctx->cmd, ctx->ns, storage_name,
ctx->status_items, &status, &error) < 0) {
client_send_line(ctx->cmd->client,
t_strconcat("* ", error, NULL));
selected_mailbox = client->mailbox != NULL &&
mailbox_equals(client->mailbox, ns, real_mailbox);
- if (imap_status_get(client, ns, real_mailbox, items,
+ if (imap_status_get(cmd, ns, real_mailbox, items,
&status, &error) < 0) {
client_send_tagline(cmd, error);
return TRUE;
break;
case MAILBOX_NAME_VALID:
+ resp_code = "";
switch (mode) {
case CLIENT_VERIFY_MAILBOX_NAME:
case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
return ns;
case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
- resp_code = IMAP_RESP_CODE_NONEXISTENT;
+ if ((cmd->cmd_flags & COMMAND_FLAG_USE_NONEXISTENT) != 0)
+ resp_code = IMAP_RESP_CODE_NONEXISTENT;
break;
case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
resp_code = "TRYCREATE";
break;
default:
- resp_code = NULL;
i_unreached();
}
+ if (*resp_code != '\0')
+ resp_code = t_strconcat("[", resp_code, "] ", NULL);
client_send_tagline(cmd, t_strconcat(
- "NO [", resp_code, "] Mailbox doesn't exist: ",
+ "NO ", resp_code, "Mailbox doesn't exist: ",
str_sanitize(orig_mailbox, MAILBOX_MAX_NAME_LEN),
NULL));
break;
}
const char *
-imap_get_error_string(const char *error_string, enum mail_error error)
+imap_get_error_string(struct client_command_context *cmd,
+ const char *error_string, enum mail_error error)
{
const char *resp_code = NULL;
resp_code = IMAP_RESP_CODE_OVERQUOTA;
break;
case MAIL_ERROR_NOTFOUND:
- resp_code = IMAP_RESP_CODE_NONEXISTENT;
+ if ((cmd->cmd_flags & COMMAND_FLAG_USE_NONEXISTENT) != 0)
+ resp_code = IMAP_RESP_CODE_NONEXISTENT;
break;
case MAIL_ERROR_EXISTS:
resp_code = IMAP_RESP_CODE_ALREADYEXISTS;
enum mail_error error;
error_string = mailbox_list_get_last_error(list, &error);
- client_send_tagline(cmd, imap_get_error_string(error_string, error));
+ client_send_tagline(cmd, imap_get_error_string(cmd, error_string,
+ error));
}
void client_send_storage_error(struct client_command_context *cmd,
}
error_string = mail_storage_get_last_error(storage, &error);
- client_send_tagline(cmd, imap_get_error_string(error_string, error));
+ client_send_tagline(cmd, imap_get_error_string(cmd, error_string,
+ error));
}
void client_send_untagged_storage_error(struct client *client,
bool client_verify_open_mailbox(struct client_command_context *cmd);
const char *
-imap_get_error_string(const char *error_string, enum mail_error error);
+imap_get_error_string(struct client_command_context *cmd,
+ const char *error_string, enum mail_error error);
/* Send last mailbox list error message to client. */
void client_send_list_error(struct client_command_context *cmd,
{ "APPEND", cmd_append, COMMAND_FLAG_BREAKS_SEQS },
{ "EXAMINE", cmd_examine, COMMAND_FLAG_BREAKS_MAILBOX },
{ "CREATE", cmd_create, 0 },
- { "DELETE", cmd_delete, 0 },
- { "RENAME", cmd_rename, 0 },
+ { "DELETE", cmd_delete, COMMAND_FLAG_USE_NONEXISTENT },
+ { "RENAME", cmd_rename, COMMAND_FLAG_USE_NONEXISTENT },
{ "LIST", cmd_list, 0 },
{ "LSUB", cmd_lsub, 0 },
{ "SELECT", cmd_select, COMMAND_FLAG_BREAKS_MAILBOX },
{ "STATUS", cmd_status, 0 },
{ "SUBSCRIBE", cmd_subscribe, 0 },
- { "UNSUBSCRIBE", cmd_unsubscribe, 0 },
+ { "UNSUBSCRIBE", cmd_unsubscribe, COMMAND_FLAG_USE_NONEXISTENT },
{ "CHECK", cmd_check, COMMAND_FLAG_BREAKS_SEQS },
{ "CLOSE", cmd_close, COMMAND_FLAG_BREAKS_MAILBOX },
COMMAND_FLAG_USES_SEQS,
/* Command requires mailbox syncing before it can do its job. */
- COMMAND_FLAG_REQUIRES_SYNC = 0x08
+ COMMAND_FLAG_REQUIRES_SYNC = 0x08,
+ /* Command allows replying with [NONEXISTENT] imap resp code.
+ Dovecot internally returns it for all kinds of commands,
+ but unfortunately RFC 5530 specifies it only for "delete something"
+ operations. */
+ COMMAND_FLAG_USE_NONEXISTENT = 0x10
};
struct command {
return 0;
}
-int imap_status_get(struct client *client, struct mail_namespace *ns,
+int imap_status_get(struct client_command_context *cmd,
+ struct mail_namespace *ns,
const char *mailbox, enum mailbox_status_items items,
struct mailbox_status *status_r, const char **error_r)
{
+ struct client *client = cmd->client;
struct mailbox *box;
enum mail_error error;
int ret;
if (ret < 0) {
struct mail_storage *storage = mailbox_get_storage(box);
*error_r = mail_storage_get_last_error(storage, &error);
- *error_r = imap_get_error_string(*error_r, error);
+ *error_r = imap_get_error_string(cmd, *error_r, error);
}
mailbox_close(&box);
return ret;
int imap_status_parse_items(struct client_command_context *cmd,
const struct imap_arg *args,
enum mailbox_status_items *items_r);
-int imap_status_get(struct client *client, struct mail_namespace *ns,
+int imap_status_get(struct client_command_context *cmd,
+ struct mail_namespace *ns,
const char *mailbox, enum mailbox_status_items items,
struct mailbox_status *status_r, const char **error_r);
void imap_status_send(struct client *client, const char *mailbox,