dovecot-2.2: pop3: Added pop3_deleted_flag setting.
dovecot at dovecot.org
dovecot at dovecot.org
Tue May 14 16:32:39 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/5984de096e3e
changeset: 16347:5984de096e3e
user: Timo Sirainen <tss at iki.fi>
date: Tue May 14 16:32:30 2013 +0300
description:
pop3: Added pop3_deleted_flag setting.
diffstat:
doc/example-config/conf.d/20-pop3.conf | 7 ++++
src/pop3/pop3-client.c | 49 +++++++++++++++++++++++++++++++--
src/pop3/pop3-client.h | 6 ++++
src/pop3/pop3-commands.c | 17 +++++++++--
src/pop3/pop3-settings.c | 4 ++-
src/pop3/pop3-settings.h | 1 +
6 files changed, 76 insertions(+), 8 deletions(-)
diffs (224 lines):
diff -r 139ab37f69df -r 5984de096e3e doc/example-config/conf.d/20-pop3.conf
--- a/doc/example-config/conf.d/20-pop3.conf Tue May 14 14:14:16 2013 +0300
+++ b/doc/example-config/conf.d/20-pop3.conf Tue May 14 16:32:30 2013 +0300
@@ -59,6 +59,13 @@
# rename: Append a temporary -2, -3, etc. counter after the UIDL.
#pop3_uidl_duplicates = allow
+ # This option changes POP3 behavior so that it's not possible to actually
+ # delete mails via POP3, only hide them from future POP3 sessions. The mails
+ # will still be counted towards user's quota until actually deleted via IMAP.
+ # Use e.g. "$POP3Deleted" as the value (it will be visible as IMAP keyword).
+ # Make sure you can legally archive mails before enabling this setting.
+ #pop3_deleted_flag =
+
# POP3 logout format string:
# %i - total number of bytes read from client
# %o - total number of bytes sent to client
diff -r 139ab37f69df -r 5984de096e3e src/pop3/pop3-client.c
--- a/src/pop3/pop3-client.c Tue May 14 14:14:16 2013 +0300
+++ b/src/pop3/pop3-client.c Tue May 14 16:32:30 2013 +0300
@@ -141,6 +141,7 @@
struct mailbox_status status;
struct mailbox_transaction_context *t;
struct mail_search_args *search_args;
+ struct mail_search_arg *sarg;
struct mail_search_context *ctx;
struct mail *mail;
uoff_t size;
@@ -158,7 +159,17 @@
t = mailbox_transaction_begin(client->mailbox, 0);
search_args = mail_search_build_init();
- mail_search_build_add_all(search_args);
+ if (client->deleted_kw != NULL) {
+ sarg = mail_search_build_add(search_args, SEARCH_KEYWORDS);
+ sarg->match_not = TRUE;
+ sarg->value.str = p_strdup(search_args->pool,
+ client->set->pop3_deleted_flag);
+ i_array_init(&client->all_seqs, 32);
+ } else {
+ mail_search_build_add_all(search_args);
+ }
+ mail_search_args_init(search_args, client->mailbox, TRUE, NULL);
+
ctx = mailbox_search_init(t, search_args, pop3_sort_program,
client->set->pop3_fast_size_lookups ? 0 :
MAIL_FETCH_VIRTUAL_SIZE, NULL);
@@ -175,6 +186,8 @@
*failed_uid_r = mail->uid;
break;
}
+ if (array_is_created(&client->all_seqs))
+ seq_range_array_add(&client->all_seqs, mail->seq);
msgnum_to_seq_map_add(&msgnum_to_seq_map, client, mail, msgnum);
if ((mail_get_flags(mail) & MAIL_SEEN) != 0)
@@ -197,7 +210,13 @@
array_free(&msgnum_to_seq_map);
return ret;
}
- i_assert(msgnum == client->messages_count);
+ i_assert(msgnum <= client->messages_count);
+ client->messages_count = msgnum;
+
+ if (!array_is_created(&client->all_seqs)) {
+ i_array_init(&client->all_seqs, 1);
+ seq_range_array_add_range(&client->all_seqs, 1, msgnum);
+ }
client->trans = t;
client->message_sizes =
@@ -211,6 +230,26 @@
return 1;
}
+static int init_pop3_deleted_flag(struct client *client, const char **error_r)
+{
+ const char *deleted_keywords[2];
+
+ if (client->set->pop3_deleted_flag[0] == '\0')
+ return 0;
+
+ deleted_keywords[0] = client->set->pop3_deleted_flag;
+ deleted_keywords[1] = NULL;
+ if (mailbox_keywords_create(client->mailbox, deleted_keywords,
+ &client->deleted_kw) < 0) {
+ *error_r = t_strdup_printf(
+ "pop3_deleted_flags: Invalid keyword '%s': %s",
+ client->set->pop3_deleted_flag,
+ mailbox_get_last_error(client->mailbox, NULL));
+ return -1;
+ }
+ return 0;
+}
+
static int init_mailbox(struct client *client, const char **error_r)
{
uint32_t failed_uid = 0, last_failed_uid = 0;
@@ -392,7 +431,8 @@
}
client->mail_set = mail_storage_get_settings(storage);
- if (init_mailbox(client, &errmsg) < 0) {
+ if (init_pop3_deleted_flag(client, &errmsg) < 0 ||
+ init_mailbox(client, &errmsg) < 0) {
i_error("Couldn't init INBOX: %s", errmsg);
client_destroy(client, "Mailbox init failed");
return -1;
@@ -553,6 +593,9 @@
message sizes. */
(void)mailbox_transaction_commit(&client->trans);
}
+ array_free(&client->all_seqs);
+ if (client->deleted_kw != NULL)
+ mailbox_keywords_unref(&client->deleted_kw);
if (client->mailbox != NULL)
mailbox_free(&client->mailbox);
if (client->anvil_sent) {
diff -r 139ab37f69df -r 5984de096e3e src/pop3/pop3-client.h
--- a/src/pop3/pop3-client.h Tue May 14 14:14:16 2013 +0300
+++ b/src/pop3/pop3-client.h Tue May 14 16:32:30 2013 +0300
@@ -1,6 +1,8 @@
#ifndef POP3_CLIENT_H
#define POP3_CLIENT_H
+#include "seq-range-array.h"
+
struct client;
struct mail_storage;
@@ -48,6 +50,7 @@
struct mail_namespace *inbox_ns;
struct mailbox *mailbox;
struct mailbox_transaction_context *trans;
+ struct mail_keywords *deleted_kw;
struct timeout *to_session_dotlock_refresh;
struct dotlock *session_dotlock;
@@ -63,6 +66,9 @@
uoff_t deleted_size;
uint32_t last_seen_pop3_msn, lowest_retr_pop3_msn;
+ /* All sequences currently visible in the mailbox. */
+ ARRAY_TYPE(seq_range) all_seqs;
+
/* [msgnum] contains mail seq. anything after it has seq = msgnum+1 */
uint32_t *msgnum_to_seq_map;
uint32_t msgnum_to_seq_map_count;
diff -r 139ab37f69df -r 5984de096e3e src/pop3/pop3-commands.c
--- a/src/pop3/pop3-commands.c Tue May 14 14:14:16 2013 +0300
+++ b/src/pop3/pop3-commands.c Tue May 14 16:32:30 2013 +0300
@@ -196,11 +196,12 @@
pop3_search_build(struct client *client, uint32_t seq)
{
struct mail_search_args *search_args;
+ struct mail_search_arg *sarg;
search_args = mail_search_build_init();
if (seq == 0) {
- mail_search_build_add_seqset(search_args,
- 1, client->messages_count);
+ sarg = mail_search_build_add(search_args, SEARCH_SEQSET);
+ sarg->value.seqset = client->all_seqs;
} else {
mail_search_build_add_seqset(search_args, seq, seq);
}
@@ -222,6 +223,15 @@
return 0;
}
+static void client_expunge(struct client *client, struct mail *mail)
+{
+ if (client->deleted_kw != NULL)
+ mail_update_keywords(mail, MODIFY_ADD, client->deleted_kw);
+ else
+ mail_expunge(mail);
+ client->expunged_count++;
+}
+
bool client_update_mails(struct client *client)
{
struct mail_search_args *search_args;
@@ -250,8 +260,7 @@
bit = 1 << (msgnum % CHAR_BIT);
if (client->deleted_bitmask != NULL &&
(client->deleted_bitmask[msgnum / CHAR_BIT] & bit) != 0) {
- mail_expunge(mail);
- client->expunged_count++;
+ client_expunge(client, mail);
} else if (client->seen_bitmask != NULL &&
(client->seen_bitmask[msgnum / CHAR_BIT] & bit) != 0) {
mail_update_flags(mail, MODIFY_ADD, MAIL_SEEN);
diff -r 139ab37f69df -r 5984de096e3e src/pop3/pop3-settings.c
--- a/src/pop3/pop3-settings.c Tue May 14 14:14:16 2013 +0300
+++ b/src/pop3/pop3-settings.c Tue May 14 16:32:30 2013 +0300
@@ -71,6 +71,7 @@
DEF(SET_STR, pop3_client_workarounds),
DEF(SET_STR, pop3_logout_format),
DEF(SET_ENUM, pop3_uidl_duplicates),
+ DEF(SET_STR, pop3_deleted_flag),
SETTING_DEFINE_LIST_END
};
@@ -86,7 +87,8 @@
.pop3_fast_size_lookups = FALSE,
.pop3_client_workarounds = "",
.pop3_logout_format = "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s",
- .pop3_uidl_duplicates = "allow:rename"
+ .pop3_uidl_duplicates = "allow:rename",
+ .pop3_deleted_flag = ""
};
static const struct setting_parser_info *pop3_setting_dependencies[] = {
diff -r 139ab37f69df -r 5984de096e3e src/pop3/pop3-settings.h
--- a/src/pop3/pop3-settings.h Tue May 14 14:14:16 2013 +0300
+++ b/src/pop3/pop3-settings.h Tue May 14 16:32:30 2013 +0300
@@ -23,6 +23,7 @@
const char *pop3_client_workarounds;
const char *pop3_logout_format;
const char *pop3_uidl_duplicates;
+ const char *pop3_deleted_flag;
enum pop3_client_workarounds parsed_workarounds;
};
More information about the dovecot-cvs
mailing list