Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9135:39c234ab0b21 HEAD
IMAP: Send [ALREADYEXISTS], [NONEXISTENT] and [TRYCREATE] resp-codes correctly.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 15 Jun 2009 21:43:37 -0400 |
parents | 67fe18c3f8dd |
children | ef7c0c3b1976 |
files | src/imap/cmd-append.c src/imap/cmd-copy.c src/imap/cmd-create.c src/imap/cmd-rename.c src/imap/cmd-subscribe.c src/imap/commands-util.c src/imap/commands-util.h |
diffstat | 7 files changed, 56 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-append.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/cmd-append.c Mon Jun 15 21:43:37 2009 -0400 @@ -455,7 +455,8 @@ struct mail_storage *storage; struct mailbox *box; - if (!client_verify_mailbox_name(cmd, name, TRUE, FALSE)) + if (!client_verify_mailbox_name(cmd, name, + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE)) return NULL; storage = client_find_storage(cmd, &name);
--- a/src/imap/cmd-copy.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/cmd-copy.c Mon Jun 15 21:43:37 2009 -0400 @@ -112,7 +112,8 @@ return TRUE; /* open the destination mailbox */ - if (!client_verify_mailbox_name(cmd, mailbox, TRUE, FALSE)) + if (!client_verify_mailbox_name(cmd, mailbox, + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE)) return TRUE; ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args);
--- a/src/imap/cmd-create.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/cmd-create.c Mon Jun 15 21:43:37 2009 -0400 @@ -35,7 +35,8 @@ full_mailbox = t_strndup(full_mailbox, len-1); } - if (!client_verify_mailbox_name(cmd, full_mailbox, FALSE, TRUE)) + if (!client_verify_mailbox_name(cmd, full_mailbox, + CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST)) return TRUE; if (mail_storage_mailbox_create(ns->storage, mailbox, directory) < 0)
--- a/src/imap/cmd-rename.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/cmd-rename.c Mon Jun 15 21:43:37 2009 -0400 @@ -16,9 +16,11 @@ if (!client_read_string_args(cmd, 2, &oldname, &newname)) return FALSE; - if (!client_verify_mailbox_name(cmd, oldname, TRUE, FALSE)) + if (!client_verify_mailbox_name(cmd, oldname, + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST)) return TRUE; - if (!client_verify_mailbox_name(cmd, newname, FALSE, TRUE)) + if (!client_verify_mailbox_name(cmd, newname, + CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST)) return TRUE; old_storage = client_find_storage(cmd, &oldname);
--- a/src/imap/cmd-subscribe.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/cmd-subscribe.c Mon Jun 15 21:43:37 2009 -0400 @@ -70,9 +70,13 @@ if (have_listable_namespace_prefix(cmd->client->user->namespaces, verify_name)) { /* subscribing to a listable namespace prefix, allow it. */ + } else if (subscribe) { + if (!client_verify_mailbox_name(cmd, verify_name, + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST)) + return TRUE; } else { if (!client_verify_mailbox_name(cmd, verify_name, - subscribe, FALSE)) + CLIENT_VERIFY_MAILBOX_NAME)) return TRUE; }
--- a/src/imap/commands-util.c Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/commands-util.c Mon Jun 15 21:43:37 2009 -0400 @@ -43,12 +43,12 @@ bool client_verify_mailbox_name(struct client_command_context *cmd, const char *mailbox, - bool should_exist, bool should_not_exist) + enum client_verify_mailbox_mode mode) { struct mail_namespace *ns; struct mailbox_list *list; enum mailbox_name_status mailbox_status; - const char *orig_mailbox, *p; + const char *orig_mailbox, *p, *resp_code; orig_mailbox = mailbox; ns = client_find_namespace(cmd, &mailbox); @@ -99,18 +99,39 @@ switch (mailbox_status) { case MAILBOX_NAME_EXISTS: - if (should_exist || !should_not_exist) + switch (mode) { + case CLIENT_VERIFY_MAILBOX_NAME: + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST: + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE: + return TRUE; + case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST: + break; + } + + if (mode == CLIENT_VERIFY_MAILBOX_NAME || + mode == CLIENT_VERIFY_MAILBOX_SHOULD_EXIST) return TRUE; - client_send_tagline(cmd, "NO Mailbox exists."); + client_send_tagline(cmd, t_strconcat( + "NO [", IMAP_RESP_CODE_ALREADYEXISTS, + "] Mailbox exists.", NULL)); break; case MAILBOX_NAME_VALID: - if (!should_exist) + switch (mode) { + case CLIENT_VERIFY_MAILBOX_NAME: + case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST: return TRUE; + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST: + resp_code = IMAP_RESP_CODE_NONEXISTENT; + break; + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE: + resp_code = "TRYCREATE"; + break; + } client_send_tagline(cmd, t_strconcat( - "NO [TRYCREATE] Mailbox doesn't exist: ", + "NO [", resp_code, "] Mailbox doesn't exist: ", str_sanitize(orig_mailbox, MAILBOX_MAX_NAME_LEN), NULL)); break;
--- a/src/imap/commands-util.h Mon Jun 15 21:22:30 2009 -0400 +++ b/src/imap/commands-util.h Mon Jun 15 21:43:37 2009 -0400 @@ -1,6 +1,17 @@ #ifndef COMMANDS_UTIL_H #define COMMANDS_UTIL_H +enum client_verify_mailbox_mode { + /* Verify only that the mailbox name is valid */ + CLIENT_VERIFY_MAILBOX_NAME, + /* If mailbox doesn't exist, fail with [NONEXISTENT] resp code */ + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST, + /* If mailbox doesn't exist, fail with [TRYCREATE] resp code */ + CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE, + /* If mailbox exists, fail with [ALREADYEXISTS] resp code */ + CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST +}; + struct msgset_generator_context { string_t *str; uint32_t first_uid, last_uid; @@ -18,15 +29,11 @@ struct mail_storage * client_find_storage(struct client_command_context *cmd, const char **mailbox); -/* If should_exist is TRUE, this function returns TRUE if the mailbox - exists. If it doesn't exist but would be a valid mailbox name, the - error message is prefixed with [TRYCREATE]. - - If should_exist is FALSE, the should_not_exist specifies if we should - return TRUE or FALSE if mailbox doesn't exist. */ +/* Returns TRUE if verifications succeeds. If it fails, a tagged NO is sent to + client. */ bool client_verify_mailbox_name(struct client_command_context *cmd, const char *mailbox, - bool should_exist, bool should_not_exist); + enum client_verify_mailbox_mode mode); /* Returns TRUE if mailbox is selected. If not, sends "No mailbox selected" error message to client. */