From: Timo Sirainen Date: Fri, 15 May 2015 11:55:21 +0000 (+0300) Subject: imap: Added %{deleted}, %{expunged} and %{trashed} to imap_logout_format X-Git-Tag: 2.2.19.rc1~487 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=760245ee05c5685122ca29427dffedbeed4b24bc;p=thirdparty%2Fdovecot%2Fcore.git imap: Added %{deleted}, %{expunged} and %{trashed} to imap_logout_format --- diff --git a/doc/example-config/conf.d/20-imap.conf b/doc/example-config/conf.d/20-imap.conf index 67f438ec05..918c78abd5 100644 --- a/doc/example-config/conf.d/20-imap.conf +++ b/doc/example-config/conf.d/20-imap.conf @@ -14,6 +14,10 @@ # %{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 '+', diff --git a/src/imap/cmd-close.c b/src/imap/cmd-close.c index c67ad2a420..4a83284e4e 100644 --- a/src/imap/cmd-close.c +++ b/src/imap/cmd-close.c @@ -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); diff --git a/src/imap/cmd-copy.c b/src/imap/cmd-copy.c index 14bde302c7..9b45f5d091 100644 --- a/src/imap/cmd-copy.c +++ b/src/imap/cmd-copy.c @@ -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); diff --git a/src/imap/cmd-expunge.c b/src/imap/cmd-expunge.c index b293dfd023..85670fe7b9 100644 --- a/src/imap/cmd-expunge.c +++ b/src/imap/cmd-expunge.c @@ -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) { diff --git a/src/imap/cmd-store.c b/src/imap/cmd-store.c index ea41a6fc42..c08225b42e 100644 --- a/src/imap/cmd-store.c +++ b/src/imap/cmd-store.c @@ -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."; diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index b78307adc8..4f12571853 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -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); diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h index 712bd39563..ed6308b36c 100644 --- a/src/imap/imap-client.h +++ b/src/imap/imap-client.h @@ -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; diff --git a/src/imap/imap-expunge.c b/src/imap/imap-expunge.c index 9c6341f0fb..17b2c9860e 100644 --- a/src/imap/imap-expunge.c +++ b/src/imap/imap-expunge.c @@ -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; } diff --git a/src/imap/imap-expunge.h b/src/imap/imap-expunge.h index 5117121723..e5b38251a1 100644 --- a/src/imap/imap-expunge.h +++ b/src/imap/imap-expunge.h @@ -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