dovecot-2.0: imap: Some mailbox accessing commands failed with w...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Mar 16 16:15:06 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/7443f0b5218f
changeset: 10918:7443f0b5218f
user: Timo Sirainen <tss at iki.fi>
date: Tue Mar 16 16:15:03 2010 +0200
description:
imap: Some mailbox accessing commands failed with wrong error message.
diffstat:
src/imap/cmd-append.c | 22 ++++++-
src/imap/cmd-copy.c | 24 ++++++-
src/imap/cmd-create.c | 35 +++++++----
src/imap/cmd-delete.c | 18 ++++-
src/imap/cmd-rename.c | 39 +++++++++---
src/imap/cmd-select.c | 20 +++++-
src/imap/cmd-status.c | 24 ++++++--
src/imap/cmd-subscribe.c | 68 +++++++++++++++-------
src/imap/imap-commands-util.c | 111 +++++++++++++-----------------------
src/imap/imap-commands-util.h | 28 +++------
10 files changed, 232 insertions(+), 157 deletions(-)
diffs (truncated from 717 to 300 lines):
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-append.c
--- a/src/imap/cmd-append.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-append.c Tue Mar 16 16:15:03 2010 +0200
@@ -454,17 +454,31 @@
{
struct mail_namespace *ns;
struct mailbox *box;
+ enum mailbox_name_status status;
+ const char *storage_name;
- ns = client_find_namespace(cmd, &name,
- CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
+ ns = client_find_namespace(cmd, name, &storage_name, &status);
if (ns == NULL)
return NULL;
+ switch (status) {
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ break;
+ case MAILBOX_NAME_EXISTS_DIR:
+ status = MAILBOX_NAME_VALID;
+ /* fall through */
+ case MAILBOX_NAME_VALID:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, name, "TRYCREATE", status);
+ return NULL;
+ }
+
if (cmd->client->mailbox != NULL &&
- mailbox_equals(cmd->client->mailbox, ns, name))
+ mailbox_equals(cmd->client->mailbox, ns, storage_name))
return cmd->client->mailbox;
- box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY |
+ box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_SAVEONLY |
MAILBOX_FLAG_KEEP_RECENT);
if (mailbox_open(box) < 0) {
client_send_storage_error(cmd, mailbox_get_storage(box));
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-copy.c
--- a/src/imap/cmd-copy.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-copy.c Tue Mar 16 16:15:03 2010 +0200
@@ -90,7 +90,8 @@
struct mailbox *destbox;
struct mailbox_transaction_context *t;
struct mail_search_args *search_args;
- const char *messageset, *mailbox, *src_uidset;
+ const char *messageset, *mailbox, *storage_name, *src_uidset;
+ enum mailbox_name_status status;
enum mailbox_sync_flags sync_flags = 0;
enum imap_sync_flags imap_flags = 0;
struct mail_transaction_commit_changes changes;
@@ -110,15 +111,28 @@
return ret < 0;
/* open the destination mailbox */
- dest_ns = client_find_namespace(cmd, &mailbox,
- CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
+ dest_ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
if (dest_ns == NULL)
return TRUE;
- if (mailbox_equals(client->mailbox, dest_ns, mailbox))
+ switch (status) {
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ break;
+ case MAILBOX_NAME_EXISTS_DIR:
+ status = MAILBOX_NAME_VALID;
+ /* fall through */
+ case MAILBOX_NAME_VALID:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, mailbox,
+ "TRYCREATE", status);
+ return NULL;
+ }
+
+ if (mailbox_equals(client->mailbox, dest_ns, storage_name))
destbox = client->mailbox;
else {
- destbox = mailbox_alloc(dest_ns->list, mailbox,
+ destbox = mailbox_alloc(dest_ns->list, storage_name,
MAILBOX_FLAG_SAVEONLY |
MAILBOX_FLAG_KEEP_RECENT);
if (mailbox_open(destbox) < 0) {
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-create.c
--- a/src/imap/cmd-create.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-create.c Tue Mar 16 16:15:03 2010 +0200
@@ -7,8 +7,9 @@
bool cmd_create(struct client_command_context *cmd)
{
+ enum mailbox_name_status status;
struct mail_namespace *ns;
- const char *mailbox, *full_mailbox;
+ const char *mailbox, *storage_name;
struct mailbox *box;
bool directory;
size_t len;
@@ -16,16 +17,15 @@
/* <mailbox> */
if (!client_read_string_args(cmd, 1, &mailbox))
return FALSE;
- full_mailbox = mailbox;
- ns = client_find_namespace(cmd, &mailbox, CLIENT_VERIFY_MAILBOX_NONE);
+ ns = client_find_namespace(cmd, mailbox, &storage_name, NULL);
if (ns == NULL)
return TRUE;
- len = strlen(full_mailbox);
- if (len == 0 || full_mailbox[len-1] != ns->sep)
+ len = strlen(mailbox);
+ if (len == 0 || mailbox[len-1] != ns->sep)
directory = FALSE;
- else if (*mailbox == '\0') {
+ else if (*storage_name == '\0') {
client_send_tagline(cmd, "NO ["IMAP_RESP_CODE_ALREADYEXISTS
"] Namespace already exists.");
return TRUE;
@@ -34,17 +34,28 @@
informing us that it wants to create children under this
mailbox. */
directory = TRUE;
- mailbox = t_strndup(mailbox, strlen(mailbox)-1);
- full_mailbox = t_strndup(full_mailbox, len-1);
+ storage_name = t_strndup(storage_name, strlen(storage_name)-1);
+ mailbox = t_strndup(mailbox, len-1);
}
- mailbox = full_mailbox;
- ns = client_find_namespace(cmd, &mailbox,
- CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST);
+ ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
if (ns == NULL)
return TRUE;
+ switch (status) {
+ case MAILBOX_NAME_VALID:
+ break;
+ case MAILBOX_NAME_EXISTS_DIR:
+ if (!directory)
+ break;
+ /* fall through */
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, mailbox, NULL, status);
+ return TRUE;
+ }
- box = mailbox_alloc(ns->list, mailbox, 0);
+ box = mailbox_alloc(ns->list, storage_name, 0);
if (mailbox_create(box, NULL, directory) < 0)
client_send_storage_error(cmd, mailbox_get_storage(box));
else
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-delete.c
--- a/src/imap/cmd-delete.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-delete.c Tue Mar 16 16:15:03 2010 +0200
@@ -6,9 +6,10 @@
bool cmd_delete(struct client_command_context *cmd)
{
struct client *client = cmd->client;
+ enum mailbox_name_status status;
struct mail_namespace *ns;
struct mailbox *box;
- const char *name;
+ const char *name, *storage_name;
/* <mailbox> */
if (!client_read_string_args(cmd, 1, &name))
@@ -20,12 +21,21 @@
return TRUE;
}
- ns = client_find_namespace(cmd, &name,
- CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST);
+ ns = client_find_namespace(cmd, name, &storage_name, &status);
if (ns == NULL)
return TRUE;
+ switch (status) {
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ case MAILBOX_NAME_EXISTS_DIR:
+ break;
+ case MAILBOX_NAME_VALID:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, name, NULL, status);
+ return TRUE;
+ }
- box = mailbox_alloc(ns->list, name, 0);
+ box = mailbox_alloc(ns->list, storage_name, 0);
if (client->mailbox != NULL &&
mailbox_backends_equal(box, client->mailbox)) {
/* deleting selected mailbox. close it first */
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-rename.c
--- a/src/imap/cmd-rename.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-rename.c Tue Mar 16 16:15:03 2010 +0200
@@ -6,40 +6,59 @@
bool cmd_rename(struct client_command_context *cmd)
{
+ enum mailbox_name_status status;
struct mail_namespace *old_ns, *new_ns;
struct mailbox *old_box, *new_box;
- const char *oldname, *newname;
+ const char *oldname, *newname, *storage_oldname, *storage_newname;
unsigned int oldlen;
/* <old name> <new name> */
if (!client_read_string_args(cmd, 2, &oldname, &newname))
return FALSE;
- old_ns = client_find_namespace(cmd, &oldname,
- CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST);
+ old_ns = client_find_namespace(cmd, oldname, &storage_oldname, &status);
if (old_ns == NULL)
return TRUE;
+ switch (status) {
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ case MAILBOX_NAME_EXISTS_DIR:
+ break;
+ case MAILBOX_NAME_VALID:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, oldname, NULL, status);
+ return TRUE;
+ }
- new_ns = client_find_namespace(cmd, &newname,
- CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST);
+ new_ns = client_find_namespace(cmd, newname, &storage_newname, &status);
if (new_ns == NULL)
return TRUE;
+ switch (status) {
+ case MAILBOX_NAME_VALID:
+ break;
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ case MAILBOX_NAME_EXISTS_DIR:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, newname, NULL, status);
+ return TRUE;
+ }
if (old_ns == new_ns) {
/* disallow box -> box/child, because it may break clients and
there's really no point in doing it anyway. */
old_ns = mailbox_list_get_namespace(old_ns->list);
- oldlen = strlen(oldname);
- if (strncmp(oldname, newname, oldlen) == 0 &&
- newname[oldlen] == old_ns->real_sep) {
+ oldlen = strlen(storage_oldname);
+ if (strncmp(storage_oldname, storage_newname, oldlen) == 0 &&
+ storage_newname[oldlen] == old_ns->real_sep) {
client_send_tagline(cmd,
"NO Can't rename mailbox under its own child.");
return TRUE;
}
}
- old_box = mailbox_alloc(old_ns->list, oldname, 0);
- new_box = mailbox_alloc(new_ns->list, newname, 0);
+ old_box = mailbox_alloc(old_ns->list, storage_oldname, 0);
+ new_box = mailbox_alloc(new_ns->list, storage_newname, 0);
if (mailbox_rename(old_box, new_box, TRUE) < 0)
client_send_storage_error(cmd, mailbox_get_storage(old_box));
else
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-select.c
--- a/src/imap/cmd-select.c Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-select.c Tue Mar 16 16:15:03 2010 +0200
@@ -342,7 +342,8 @@
struct mailbox *box;
struct imap_select_context *ctx;
const struct imap_arg *args;
- const char *mailbox;
+ enum mailbox_name_status status;
+ const char *mailbox, *storage_name;
int ret;
/* <mailbox> [(optional parameters)] */
@@ -357,10 +358,21 @@
ctx = p_new(cmd->pool, struct imap_select_context, 1);
ctx->cmd = cmd;
- ctx->ns = client_find_namespace(cmd, &mailbox,
- CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
+ ctx->ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
if (ctx->ns == NULL)
return TRUE;
+ switch (status) {
+ case MAILBOX_NAME_EXISTS_MAILBOX:
+ break;
+ case MAILBOX_NAME_EXISTS_DIR:
+ status = MAILBOX_NAME_VALID;
+ /* fall through */
+ case MAILBOX_NAME_VALID:
+ case MAILBOX_NAME_INVALID:
+ case MAILBOX_NAME_NOINFERIORS:
+ client_fail_mailbox_name_status(cmd, mailbox, NULL, status);
More information about the dovecot-cvs
mailing list