]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added pop3_save_uidl setting.
authorTimo Sirainen <tss@iki.fi>
Mon, 31 Aug 2009 23:05:22 +0000 (19:05 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 31 Aug 2009 23:05:22 +0000 (19:05 -0400)
When UIDLs are sent to client, save them to dovecot-uidlist. This allows
changing pop3_uidl_format without messages getting re-downloaded. It's also
useful with virtual POP3 INBOX when UIDLs are based on IMAP UIDs that may
not be as stable as in non-virtual INBOX.

--HG--
branch : HEAD

13 files changed:
src/lib-storage/index/cydir/cydir-mail.c
src/lib-storage/index/dbox/dbox-mail.c
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/raw/raw-mail.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.h
src/lib-storage/mail.c
src/lib-storage/test-mail.c
src/plugins/virtual/virtual-mail.c
src/pop3/pop3-commands.c
src/pop3/pop3-settings.c
src/pop3/pop3-settings.h

index cc8e7254f71a4cb61262327f0b447b17f6834d41..7013f49837065abc2984e8406bb1757e5b3808dc 100644 (file)
@@ -145,6 +145,7 @@ struct mail_vfuncs cydir_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        index_mail_update_uid,
+       NULL,
        index_mail_expunge,
        index_mail_set_cache_corrupted,
        index_mail_get_index_mail
index 78d1e985e3cda82b0ca0e33e2c3a428e1134a04d..ea18908ad7a4fe51b3326d84c880b93da51ca668 100644 (file)
@@ -416,6 +416,7 @@ struct mail_vfuncs dbox_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        index_mail_update_uid,
+       NULL,
        index_mail_expunge,
        index_mail_set_cache_corrupted,
        index_mail_get_index_mail
index 4a9765e69e4f4c1f64f1fd3de5806ea9a9bee5c8..01e8aba436d0bc2e288c1c3b8c24062211b15f73 100644 (file)
@@ -503,6 +503,23 @@ static void maildir_mail_update_uid(struct mail *_mail, uint32_t new_uid)
        index_mail_update_uid(_mail, new_uid);
 }
 
+static void maildir_update_pop3_uidl(struct mail *_mail, const char *uidl)
+{
+       struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
+       const char *fname;
+
+       if (maildir_mail_get_special(_mail, MAIL_FETCH_UIDL_FILE_NAME,
+                                    &fname) == 0 &&
+           strcmp(uidl, fname) == 0) {
+               /* special case optimization: empty UIDL means the same
+                  as base filename */
+               uidl = "";
+       }
+
+       maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
+                               MAILDIR_UIDLIST_REC_EXT_POP3_UIDL, uidl);
+}
+
 static void maildir_mail_set_cache_corrupted(struct mail *_mail,
                                             enum mail_fetch_field field)
 {
@@ -564,6 +581,7 @@ struct mail_vfuncs maildir_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        maildir_mail_update_uid,
+       maildir_update_pop3_uidl,
        index_mail_expunge,
        maildir_mail_set_cache_corrupted,
        index_mail_get_index_mail
index 0bbcea3b2afaf7a52a4e4ab09e6827d9f3d74d5e..a42c6b465d153b5e891e468c8676a042f68a9a79 100644 (file)
@@ -375,6 +375,7 @@ struct mail_vfuncs mbox_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        index_mail_update_uid,
+       NULL,
        index_mail_expunge,
        index_mail_set_cache_corrupted,
        index_mail_get_index_mail
index 382ec489c4642b2e2517c38e6b9a3ec9bcb5a3d2..9fbd96e2b00d6d4f535fb370c1ba3b6562c4d5e6 100644 (file)
@@ -136,6 +136,7 @@ struct mail_vfuncs raw_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        index_mail_update_uid,
+       NULL,
        index_mail_expunge,
        index_mail_set_cache_corrupted,
        index_mail_get_index_mail
index 95fea8b6a22b0920d1e25869729d8ce1da25041d..a26b152b141cf75fa0c1dcb1679df6167d129c65 100644 (file)
@@ -296,6 +296,7 @@ struct mail_vfuncs {
                                struct mail_keywords *keywords);
        void (*update_modseq)(struct mail *mail, uint64_t min_modseq);
        void (*update_uid)(struct mail *mail, uint32_t new_uid);
+       void (*update_pop3_uidl)(struct mail *mail, const char *uidl);
        void (*expunge)(struct mail *mail);
        void (*set_cache_corrupted)(struct mail *mail,
                                    enum mail_fetch_field field);
index ba83b4476672b6f2cb96833e08a2d998cb49b014..bd91e5b5be31dace5016a878210b22185c438e37 100644 (file)
@@ -657,6 +657,8 @@ void mail_update_modseq(struct mail *mail, uint64_t min_modseq);
 /* Update message's UID. The new UID must not be lower than next_uid at the
    commit time, otherwise the UID update fails and is just ignored. */
 void mail_update_uid(struct mail *mail, uint32_t new_uid);
+/* Update message's POP3 UIDL (if possible). */
+void mail_update_pop3_uidl(struct mail *mail, const char *uidl);
 /* Expunge this message. Sequence numbers don't change until commit. */
 void mail_expunge(struct mail *mail);
 /* Mark a cached field corrupted and have it recalculated. */
index fc947a4d1654a1bf70f4e5246ff4e5c62026bf31..6dc2235dc49049728923d521da99205b71e79fdc 100644 (file)
@@ -210,6 +210,14 @@ void mail_update_uid(struct mail *mail, uint32_t new_uid)
        p->v.update_uid(mail, new_uid);
 }
 
+void mail_update_pop3_uidl(struct mail *mail, const char *uidl)
+{
+       struct mail_private *p = (struct mail_private *)mail;
+
+       if (p->v.update_pop3_uidl != NULL)
+               p->v.update_pop3_uidl(mail, uidl);
+}
+
 void mail_expunge(struct mail *mail)
 {
        struct mail_private *p = (struct mail_private *)mail;
index 7c1cf205f4f1f2be656ea85915a47c2b1d3a6bb9..0c2a6c17308dbf27e058ead960dbe0136a14feb9 100644 (file)
@@ -233,6 +233,7 @@ struct mail_vfuncs test_mail_vfuncs = {
        test_mail_update_keywords,
        test_mail_update_modseq,
        test_mail_update_uid,
+       NULL,
        test_mail_expunge,
        test_mail_set_cache_corrupted,
        test_mail_get_index_mail
index e0358848353a23677c2e47804300cc864774ef5a..d3f23ac5e63bc1d12e6b4de4e56b629b69f30cdf 100644 (file)
@@ -347,6 +347,13 @@ virtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
        return 0;
 }
 
+static void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
+{
+       struct virtual_mail *vmail = (struct virtual_mail *)mail;
+
+       mail_update_pop3_uidl(vmail->backend_mail, uidl);
+}
+
 static void virtual_mail_expunge(struct mail *mail)
 {
        struct virtual_mail *vmail = (struct virtual_mail *)mail;
@@ -399,6 +406,7 @@ struct mail_vfuncs virtual_mail_vfuncs = {
        index_mail_update_keywords,
        index_mail_update_modseq,
        index_mail_update_uid,
+       virtual_mail_update_pop3_uidl,
        virtual_mail_expunge,
        virtual_mail_set_cache_corrupted,
        virtual_mail_get_index_mail
index e163d0da9728453fb3ebb41c3b109d5334a69b72..551fe0996223d595ace0626c85a795071b0315aa 100644 (file)
@@ -521,7 +521,7 @@ struct cmd_uidl_context {
        unsigned int message;
 };
 
-static void pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
+static bool pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
                         struct var_expand_table *tab, string_t *str)
 {
        char uid_str[MAX_INT_STRLEN];
@@ -530,13 +530,13 @@ static void pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
        if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &uidl) == 0 &&
            *uidl != '\0') {
                str_append(str, uidl);
-               return;
+               return TRUE;
        }
 
        if (client->set->pop3_reuse_xuidl &&
            mail_get_first_header(ctx->mail, "X-UIDL", &uidl) > 0) {
                str_append(str, uidl);
-               return;
+               return FALSE;
        }
 
        if ((client->uidl_keymask & UIDL_UID) != 0) {
@@ -562,6 +562,7 @@ static void pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
                }
        }
        var_expand(str, client->mail_set->pop3_uidl_format, tab);
+       return FALSE;
 }
 
 static bool list_uids_iter(struct client *client, struct cmd_uidl_context *ctx)
@@ -576,6 +577,7 @@ static bool list_uids_iter(struct client *client, struct cmd_uidl_context *ctx)
        struct var_expand_table *tab;
        string_t *str;
        int ret;
+       unsigned int uidl_pos;
        bool found = FALSE;
 
        tab = t_malloc(sizeof(static_tab));
@@ -595,7 +597,10 @@ static bool list_uids_iter(struct client *client, struct cmd_uidl_context *ctx)
                str_truncate(str, 0);
                str_printfa(str, ctx->message == 0 ? "%u " : "+OK %u ",
                            ctx->mail->seq);
-               pop3_get_uid(client, ctx, tab, str);
+               uidl_pos = str_len(str);
+               if (!pop3_get_uid(client, ctx, tab, str) &&
+                   client->set->pop3_save_uidl)
+                       mail_update_pop3_uidl(ctx->mail, str_c(str) + uidl_pos);
 
                ret = client_send_line(client, "%s", str_c(str));
                if (ret < 0)
index d16d69236ff616cb90aa740c03f2f9d9913fe3d4..01bcd836f0479ffb6f896676036eecfb209e75be 100644 (file)
@@ -24,6 +24,7 @@ static struct setting_define pop3_setting_defines[] = {
        DEF(SET_BOOL, pop3_no_flag_updates),
        DEF(SET_BOOL, pop3_enable_last),
        DEF(SET_BOOL, pop3_reuse_xuidl),
+       DEF(SET_BOOL, pop3_save_uidl),
        DEF(SET_BOOL, pop3_lock_session),
        DEF(SET_STR, pop3_client_workarounds),
        DEF(SET_STR, pop3_logout_format),
@@ -39,6 +40,7 @@ static struct pop3_settings pop3_default_settings = {
        MEMBER(pop3_no_flag_updates) FALSE,
        MEMBER(pop3_enable_last) FALSE,
        MEMBER(pop3_reuse_xuidl) FALSE,
+       MEMBER(pop3_save_uidl) FALSE,
        MEMBER(pop3_lock_session) FALSE,
        MEMBER(pop3_client_workarounds) "",
        MEMBER(pop3_logout_format) "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s"
index 369c2458300315b05fab10df1a1b1b647e5ad298..f7d23611b4e84c153c1e4cf185734636b9c06528 100644 (file)
@@ -12,6 +12,7 @@ struct pop3_settings {
        bool pop3_no_flag_updates;
        bool pop3_enable_last;
        bool pop3_reuse_xuidl;
+       bool pop3_save_uidl;
        bool pop3_lock_session;
        const char *pop3_client_workarounds;
        const char *pop3_logout_format;