]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Don't send NONEXISTENT resp code to non-delete operations.
authorTimo Sirainen <tss@iki.fi>
Mon, 23 Nov 2009 20:01:45 +0000 (15:01 -0500)
committerTimo Sirainen <tss@iki.fi>
Mon, 23 Nov 2009 20:01:45 +0000 (15:01 -0500)
--HG--
branch : HEAD

src/imap/cmd-list.c
src/imap/cmd-status.c
src/imap/imap-commands-util.c
src/imap/imap-commands-util.h
src/imap/imap-commands.c
src/imap/imap-commands.h
src/imap/imap-status.c
src/imap/imap-status.h

index 883b2ad563a9181dd84be32bdfa07f16fff97885..393388577c6b625e1f1df3e87cfd5a8b70605a82 100644 (file)
@@ -320,7 +320,7 @@ static void list_send_status(struct cmd_list_context *ctx, const char *name)
        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));
index 817a14eb34434d22ecc9e571588fc570b6d93144..cf59180c30ceeaf80f62a3b7f2354faaee0b92e7 100644 (file)
@@ -38,7 +38,7 @@ bool cmd_status(struct client_command_context *cmd)
 
        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;
index 6fdaffb7a6c4c6f030de3848f3e7e8eba4aa187a..ff6bea47aca8b06293e342005c2cebf5b1d3fc44 100644 (file)
@@ -111,23 +111,26 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp,
                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;
@@ -161,7 +164,8 @@ 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)
 {
        const char *resp_code = NULL;
 
@@ -182,7 +186,8 @@ imap_get_error_string(const char *error_string, enum mail_error error)
                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;
@@ -207,7 +212,8 @@ void client_send_list_error(struct client_command_context *cmd,
        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,
@@ -225,7 +231,8 @@ 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,
index c1964c56df33197bffdfd2ec3d9118f013e7901f..f738d116d0bf11f876422c7c6fa2389b56f18995 100644 (file)
@@ -33,7 +33,8 @@ client_find_namespace(struct client_command_context *cmd, const char **mailbox,
 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,
index 6a2661dfe87145dd44603ceb1730c4686e1d7653..ea7c50ac205525db12c2baf27832690a1992ff85 100644 (file)
@@ -15,14 +15,14 @@ static const struct command imap4rev1_commands[] = {
        { "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 },
index c385f401cf491afbdaa7d292f4bcc718b54a3798..dc6391c8194401f0c4cf78e9af07f061e2f1530a 100644 (file)
@@ -24,7 +24,12 @@ enum command_flags {
                                          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 {
index 9aa8e63d043f37cab6892de104c7868eacbdebd2..285c20d70c5e041c1e3a0b43242e1bd23a5dbebb 100644 (file)
@@ -49,10 +49,12 @@ int imap_status_parse_items(struct client_command_context *cmd,
        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;
@@ -77,7 +79,7 @@ int imap_status_get(struct client *client, struct mail_namespace *ns,
        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;
index dcb7b0b5940401d76438ebc4083f09f47a65e2f3..cfccaff899bbc3fd06390363268d4f9a8bded394 100644 (file)
@@ -4,7 +4,8 @@
 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,