]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Added %{deleted}, %{expunged} and %{trashed} to imap_logout_format
authorTimo Sirainen <tss@iki.fi>
Fri, 15 May 2015 11:55:21 +0000 (14:55 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 15 May 2015 11:55:21 +0000 (14:55 +0300)
doc/example-config/conf.d/20-imap.conf
src/imap/cmd-close.c
src/imap/cmd-copy.c
src/imap/cmd-expunge.c
src/imap/cmd-store.c
src/imap/imap-client.c
src/imap/imap-client.h
src/imap/imap-expunge.c
src/imap/imap-expunge.h

index 67f438ec05a6e610cba0981be690bad10b58745d..918c78abd595cea4a09ae1a5245ddc456a1175ee 100644 (file)
 #  %{fetch_hdr_bytes} - Number of bytes with mail header data sent to client
 #  %{fetch_body_count} - Number of mails with mail body data sent to client
 #  %{fetch_body_bytes} - Number of bytes with mail body data sent to client
+#  %{deleted} - Number of mails where client added \Deleted flag
+#  %{expunged} - Number of mails that client expunged
+#  %{trashed} - Number of mails that client copied/moved to the
+#               special_use=\Trash mailbox.
 #imap_logout_format = in=%i out=%o
 
 # Override the IMAP CAPABILITY response. If the value begins with '+',
index c67ad2a4207b9728901c9f4f921c5b51fe1e5846..4a83284e4e88a39a7682d083a55fa20b5616f092 100644 (file)
@@ -19,7 +19,7 @@ bool cmd_close(struct client_command_context *cmd)
        client->mailbox = NULL;
 
        storage = mailbox_get_storage(mailbox);
-       if (imap_expunge(mailbox, NULL) < 0) {
+       if (imap_expunge(mailbox, NULL, &client->expunged_count) < 0) {
                errstr = mailbox_get_last_error(mailbox, &error);
                if (error != MAIL_ERROR_PERM)
                        client_send_untagged_storage_error(client, storage);
index 14bde302c7b09dd498f740d91ab6705e59464c97..9b45f5d0910c32d48a87f5c742eff055f08dce57 100644 (file)
@@ -86,6 +86,19 @@ static int fetch_and_copy(struct client *client, bool move,
        return ret;
 }
 
+static void copy_update_trashed(struct client *client, struct mailbox *box,
+                               unsigned int count)
+{
+       const struct mailbox_settings *set;
+
+       set = mailbox_settings_find(mailbox_get_namespace(box),
+                                   mailbox_get_vname(box));
+       if (set != NULL && set->special_use[0] != '\0' &&
+           str_array_icase_find(t_strsplit_spaces(set->special_use, " "),
+                                "\\Trash"))
+               client->trashed_count += count;
+}
+
 static bool cmd_copy_full(struct client_command_context *cmd, bool move)
 {
        struct client *client = cmd->client;
@@ -147,6 +160,7 @@ static bool cmd_copy_full(struct client_command_context *cmd, bool move)
                pool_unref(&changes.pool);
        } else if (move) {
                i_assert(copy_count == seq_range_count(&changes.saved_uids));
+               copy_update_trashed(client, destbox, copy_count);
 
                str_printfa(msg, "* OK [COPYUID %u %s ",
                            changes.uid_validity, src_uidset);
@@ -159,6 +173,7 @@ static bool cmd_copy_full(struct client_command_context *cmd, bool move)
                pool_unref(&changes.pool);
        } else {
                i_assert(copy_count == seq_range_count(&changes.saved_uids));
+               copy_update_trashed(client, destbox, copy_count);
 
                str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity,
                            src_uidset);
index b293dfd02351b81df1fdfdd00d2ebe33ff7a7129..85670fe7b9e84fc5b83a6374b6015d7b338e62a8 100644 (file)
@@ -29,7 +29,7 @@ cmd_expunge_finish(struct client_command_context *cmd,
        int ret;
 
        ret = imap_expunge(client->mailbox, search_args == NULL ? NULL :
-                          search_args->args);
+                          search_args->args, &client->expunged_count);
        if (search_args != NULL)
                mail_search_args_unref(&search_args);
        if (ret < 0) {
index ea41a6fc424357da2d05449b70a0f6f838e3b794..c08225b42eb4869cc809a10621022ce0755c68a3 100644 (file)
@@ -136,6 +136,8 @@ bool cmd_store(struct client_command_context *cmd)
        const char *set, *reply, *tagged_reply;
        string_t *str;
        int ret;
+       bool update_deletes;
+       unsigned int deleted_count;
 
        if (!client_read_args(cmd, 0, 0, &args))
                return FALSE;
@@ -188,6 +190,9 @@ bool cmd_store(struct client_command_context *cmd)
                                                   &modified_set);
        }
 
+       update_deletes = (ctx.flags & MAIL_DELETED) != 0 &&
+               ctx.modify_type != MODIFY_REMOVE;
+       deleted_count = 0;
        while (mailbox_search_next(search_ctx, &mail)) {
                if (ctx.max_modseq < (uint64_t)-1) {
                        /* check early so there's less work for transaction
@@ -197,6 +202,10 @@ bool cmd_store(struct client_command_context *cmd)
                                continue;
                        }
                }
+               if (update_deletes) {
+                       if ((mail_get_flags(mail) & MAIL_DELETED) == 0)
+                               deleted_count++;
+               }
                if (ctx.modify_type == MODIFY_REPLACE || ctx.flags != 0)
                        mail_update_flags(mail, ctx.modify_type, ctx.flags);
                if (ctx.modify_type == MODIFY_REPLACE || ctx.keywords != NULL) {
@@ -218,6 +227,7 @@ bool cmd_store(struct client_command_context *cmd)
                client_send_box_error(cmd, client->mailbox);
                return TRUE;
        }
+       client->deleted_count += deleted_count;
 
        if (array_count(&modified_set) == 0)
                tagged_reply = "OK Store completed.";
index b78307adc80d78288d950c8819937a58acfe4528..4f1257185393ecfc892399b6c133420d7ae76cef 100644 (file)
@@ -221,6 +221,9 @@ static const char *client_stats(struct client *client)
                { '\0', NULL, "fetch_hdr_bytes" },
                { '\0', NULL, "fetch_body_count" },
                { '\0', NULL, "fetch_body_bytes" },
+               { '\0', NULL, "deleted" },
+               { '\0', NULL, "expunged" },
+               { '\0', NULL, "trashed" },
                { '\0', NULL, NULL }
        };
        struct var_expand_table *tab;
@@ -236,6 +239,9 @@ static const char *client_stats(struct client *client)
        tab[4].value = dec2str(client->fetch_hdr_bytes);
        tab[5].value = dec2str(client->fetch_body_count);
        tab[6].value = dec2str(client->fetch_body_bytes);
+       tab[7].value = dec2str(client->deleted_count);
+       tab[8].value = dec2str(client->expunged_count);
+       tab[9].value = dec2str(client->trashed_count);
 
        str = t_str_new(128);
        var_expand(str, client->set->imap_logout_format, tab);
index 712bd39563630ca055d329a448690a4575afbc80..ed6308b36cd9288ee0c681ea3f757888aa4f52bb 100644 (file)
@@ -139,6 +139,7 @@ struct client {
        /* For imap_logout_format statistics: */
        unsigned int fetch_hdr_count, fetch_body_count;
        uint64_t fetch_hdr_bytes, fetch_body_bytes;
+       unsigned int deleted_count, expunged_count, trashed_count;
 
        /* SEARCHRES extension: Last saved SEARCH result */
        ARRAY_TYPE(seq_range) search_saved_uidset;
index 9c6341f0fbc9b031ce90586eb2590e1224ce9b19..17b2c9860e6aca852894372de0b0421c661d1c94 100644 (file)
@@ -5,7 +5,8 @@
 #include "mail-search-build.h"
 #include "imap-expunge.h"
 
-int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg)
+int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg,
+                unsigned int *expunged_count)
 {
        struct mail_search_context *ctx;
         struct mailbox_transaction_context *t;
@@ -31,6 +32,7 @@ int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg)
        mail_search_args_unref(&search_args);
 
        while (mailbox_search_next(ctx, &mail)) {
+               *expunged_count += 1;
                mail_expunge(mail);
                expunges = TRUE;
        }
index 51171217237863e35568034033b0836fa237f3d7..e5b38251a16002b9acb7bf0190d6eb5e22fda06f 100644 (file)
@@ -3,7 +3,8 @@
 
 struct mail_search_arg;
 
-int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg)
+int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg,
+                unsigned int *expunged_count)
        ATTR_NULL(2);
 
 #endif