]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
pop3: Added pop3_fast_size_lookups setting.
authorTimo Sirainen <tss@iki.fi>
Fri, 1 Oct 2010 15:39:11 +0000 (16:39 +0100)
committerTimo Sirainen <tss@iki.fi>
Fri, 1 Oct 2010 15:39:11 +0000 (16:39 +0100)
doc/example-config/conf.d/20-pop3.conf
src/pop3/pop3-client.c
src/pop3/pop3-settings.c
src/pop3/pop3-settings.h

index 1b32fda753529b91da2ce2275172ec10db90cb52..3559b9a7b031bfbfbd7b080b1ec3307546847c13 100644 (file)
@@ -19,6 +19,13 @@ protocol pop3 {
   # Keep the mailbox locked for the entire POP3 session.
   #pop3_lock_session = no
 
+  # POP3 requires message sizes to be listed as if they had CR+LF linefeeds.
+  # Many POP3 servers violate this by returning the sizes with LF linefeeds,
+  # because it's faster to get. When this setting is enabled, Dovecot still
+  # tries to do the right thing first, but if that requires opening the
+  # message, it fallbacks to the easier (but incorrect) size.
+  #pop3_fast_size_lookups = no
+
   # POP3 UIDL (unique mail identifier) format to use. You can use following
   # variables, along with the variable modifiers described in
   # doc/wiki/Variables.txt (e.g. %Uf for the filename in uppercase)
index 7baf191670706472516f51596b91f731fdf14316..cfb125134ba879dc506927aa98042f0fa97f41ef 100644 (file)
@@ -64,6 +64,45 @@ static void client_idle_timeout(struct client *client)
        }
 }
 
+static int
+pop3_mail_get_size(struct client *client, struct mail *mail, uoff_t *size_r)
+{
+       struct mail_storage *storage;
+       enum mail_error error;
+       int ret;
+
+       if (!client->set->pop3_fast_size_lookups)
+               return mail_get_virtual_size(mail, size_r);
+
+       /* first try to get the virtual size */
+       mail->lookup_abort = MAIL_LOOKUP_ABORT_READ_MAIL;
+       ret = mail_get_virtual_size(mail, size_r);
+       mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
+       if (ret == 0)
+               return 0;
+
+       storage = mailbox_get_storage(mail->box);
+       (void)mail_storage_get_last_error(storage, &error);
+       if (error != MAIL_ERROR_NOTPOSSIBLE)
+               return -1;
+
+       /* virtual size not available with a fast lookup.
+          fallback to trying the physical size */
+       mail->lookup_abort = MAIL_LOOKUP_ABORT_READ_MAIL;
+       ret = mail_get_physical_size(mail, size_r);
+       mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
+       if (ret == 0)
+               return 0;
+
+       (void)mail_storage_get_last_error(storage, &error);
+       if (error != MAIL_ERROR_NOTPOSSIBLE)
+               return -1;
+
+       /* no way to quickly get the size. fallback to doing a slow virtual
+          size lookup */
+       return mail_get_virtual_size(mail, size_r);
+}
+
 static int read_mailbox(struct client *client, uint32_t *failed_uid_r)
 {
         struct mailbox_status status;
@@ -94,7 +133,7 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r)
 
        mail = mail_alloc(t, MAIL_FETCH_VIRTUAL_SIZE, NULL);
        while (mailbox_search_next(ctx, mail)) {
-               if (mail_get_virtual_size(mail, &size) < 0) {
+               if (pop3_mail_get_size(client, mail, &size) < 0) {
                        ret = mail->expunged ? 0 : -1;
                        *failed_uid_r = mail->uid;
                        break;
index 0fa239f6ca5fc40e2d7e4b7ac2e31af0b68b411e..b6e3843aa88dd3b68c5620b741e1a50e6b3e6d5a 100644 (file)
@@ -68,6 +68,7 @@ static const struct setting_define pop3_setting_defines[] = {
        DEF(SET_BOOL, pop3_reuse_xuidl),
        DEF(SET_BOOL, pop3_save_uidl),
        DEF(SET_BOOL, pop3_lock_session),
+       DEF(SET_BOOL, pop3_fast_size_lookups),
        DEF(SET_STR, pop3_client_workarounds),
        DEF(SET_STR, pop3_logout_format),
 
@@ -83,6 +84,7 @@ static const struct pop3_settings pop3_default_settings = {
        .pop3_reuse_xuidl = FALSE,
        .pop3_save_uidl = FALSE,
        .pop3_lock_session = FALSE,
+       .pop3_fast_size_lookups = FALSE,
        .pop3_client_workarounds = "",
        .pop3_logout_format = "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s"
 };
index 43c148b58686a0554373ec524805cd1c6874207a..174e2ba4ba2e4e39c6dfb0869e2247894ffe5543 100644 (file)
@@ -20,6 +20,7 @@ struct pop3_settings {
        bool pop3_reuse_xuidl;
        bool pop3_save_uidl;
        bool pop3_lock_session;
+       bool pop3_fast_size_lookups;
        const char *pop3_client_workarounds;
        const char *pop3_logout_format;