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;
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);
*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)
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 =
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;
}
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;
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) {
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);
}
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;
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);
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
};
.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[] = {