]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: If mail's input stream is changed, don't assume virtual size = physical size.
authorTimo Sirainen <tss@iki.fi>
Fri, 28 Jan 2011 17:39:00 +0000 (19:39 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 28 Jan 2011 17:39:00 +0000 (19:39 +0200)
src/lib-storage/index/imapc/imapc-mail.c
src/lib-storage/index/imapc/imapc-search.c

index 6407343f196b149fe843e50ba5351de00a805c79..cb3e3deccdd3ff8a8b704644d830e1373d688d00 100644 (file)
@@ -43,13 +43,43 @@ static int imapc_mail_get_save_date(struct mail *_mail, time_t *date_r)
        return 0;
 }
 
+static int imapc_mail_get_sizes(struct index_mail *mail)
+{
+       struct message_size hdr_size, body_size;
+       struct istream *input;
+       uoff_t old_offset;
+
+       /* fallback to reading the file */
+       old_offset = mail->data.stream->v_offset;
+       if (mail_get_stream(&mail->mail.mail,
+                           &hdr_size, &body_size, &input) < 0)
+               return -1;
+       i_stream_seek(mail->data.stream, old_offset);
+       return 0;
+}
+
+static int imapc_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
+{
+       struct index_mail *mail = (struct index_mail *)_mail;
+       struct index_mail_data *data = &mail->data;
+
+       if (data->virtual_size == (uoff_t)-1) {
+               if (imapc_mail_get_sizes(mail) < 0)
+                       return -1;
+       }
+       *size_r = data->virtual_size;
+       return 0;
+}
+
 static int imapc_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
 {
        struct index_mail *mail = (struct index_mail *)_mail;
        struct index_mail_data *data = &mail->data;
 
-       if (data->physical_size == (uoff_t)-1)
-               return -1;
+       if (data->physical_size == (uoff_t)-1) {
+               if (imapc_mail_get_sizes(mail) < 0)
+                       return -1;
+       }
        *size_r = data->physical_size;
        return 0;
 }
@@ -82,7 +112,7 @@ struct mail_vfuncs imapc_mail_vfuncs = {
        index_mail_get_date,
        imapc_mail_get_received_date,
        imapc_mail_get_save_date,
-       imapc_mail_get_physical_size, /* physical = virtual in our case */
+       imapc_mail_get_virtual_size,
        imapc_mail_get_physical_size,
        index_mail_get_first_header,
        index_mail_get_headers,
index 335b79a7707e57b73bd635ec82a224f9bf979a3f..5553fec87502d3d0b005ce044ead1ec6f35ef51a 100644 (file)
@@ -104,9 +104,7 @@ imapc_fetch_stream(struct index_mail *imail, const char *value, bool body)
                        i_stream_unref(&imail->data.stream);
                        return;
                }
-       }
-
-       if (body) {
+       } else if (body) {
                ret = i_stream_get_size(imail->data.stream, TRUE, &size);
                if (ret < 0) {
                        i_stream_unref(&imail->data.stream);
@@ -114,6 +112,8 @@ imapc_fetch_stream(struct index_mail *imail, const char *value, bool body)
                }
                i_assert(ret != 0);
                imail->data.physical_size = size;
+               /* we'll assume that the remote server is working properly and
+                  sending CRLF linefeeds */
                imail->data.virtual_size = size;
        }