dovecot-2.2: imapc: Added imapc_features=rfc822.size setting to ...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 20 03:26:30 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/6a8b78450202
changeset: 14403:6a8b78450202
user: Timo Sirainen <tss at iki.fi>
date: Fri Mar 30 05:20:08 2012 +0300
description:
imapc: Added imapc_features=rfc822.size setting to use RFC822.size for physical sizes.
diffstat:
src/lib-storage/index/imapc/imapc-mail-fetch.c | 18 ++++++++
src/lib-storage/index/imapc/imapc-mail.c | 53 ++++++++++++++++++-------
src/lib-storage/index/imapc/imapc-settings.c | 41 ++++++++++++++++++++
src/lib-storage/index/imapc/imapc-settings.h | 9 ++++
src/lib-storage/index/imapc/imapc-storage.h | 6 ++
5 files changed, 112 insertions(+), 15 deletions(-)
diffs (264 lines):
diff -r 87cd04f35f82 -r 6a8b78450202 src/lib-storage/index/imapc/imapc-mail-fetch.c
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Fri Mar 30 05:11:09 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Fri Mar 30 05:20:08 2012 +0300
@@ -95,6 +95,8 @@
str_printfa(str, "UID FETCH %u (", _mail->uid);
if ((fields & MAIL_FETCH_RECEIVED_DATE) != 0)
str_append(str, "INTERNALDATE ");
+ if ((fields & MAIL_FETCH_PHYSICAL_SIZE) != 0)
+ str_append(str, "RFC822.SIZE ");
if ((fields & MAIL_FETCH_GUID) != 0) {
str_append(str, mbox->guid_fetch_field_name);
str_append_c(str, ' ');
@@ -157,6 +159,10 @@
if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 &&
data->received_date == (time_t)-1)
fields |= MAIL_FETCH_RECEIVED_DATE;
+ if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0 &&
+ data->physical_size == (uoff_t)-1 &&
+ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE))
+ fields |= MAIL_FETCH_PHYSICAL_SIZE;
if ((data->wanted_fields & MAIL_FETCH_GUID) != 0 &&
data->guid == NULL && mbox->guid_fetch_field_name != NULL)
fields |= MAIL_FETCH_GUID;
@@ -181,6 +187,11 @@
return FALSE;
fields &= ~MAIL_FETCH_RECEIVED_DATE;
}
+ if ((fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) {
+ if (imail->imail.data.physical_size == (uoff_t)-1)
+ return FALSE;
+ fields &= ~MAIL_FETCH_PHYSICAL_SIZE;
+ }
if ((fields & MAIL_FETCH_GUID) != 0) {
if (imail->imail.data.guid == NULL)
return FALSE;
@@ -357,6 +368,7 @@
(struct imapc_mailbox *)mail->imail.mail.mail.box;
const char *key, *value;
unsigned int i;
+ uoff_t size;
time_t t;
int tz;
bool match = FALSE;
@@ -377,6 +389,12 @@
imap_parse_datetime(value, &t, &tz))
mail->imail.data.received_date = t;
match = TRUE;
+ } else if (strcasecmp(key, "RFC822.SIZE") == 0) {
+ if (imap_arg_get_atom(&args[i+1], &value) &&
+ str_to_uoff(value, &size) == 0 &&
+ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE))
+ mail->imail.data.physical_size = size;
+ match = TRUE;
} else if (strcasecmp(key, "X-GM-MSGID") == 0 ||
strcasecmp(key, "X-GUID") == 0) {
if (imap_arg_get_astring(&args[i+1], &value)) {
diff -r 87cd04f35f82 -r 6a8b78450202 src/lib-storage/index/imapc/imapc-mail.c
--- a/src/lib-storage/index/imapc/imapc-mail.c Fri Mar 30 05:11:09 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail.c Fri Mar 30 05:20:08 2012 +0300
@@ -107,29 +107,50 @@
static int imapc_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
{
+ struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
struct istream *input;
uoff_t old_offset;
int ret;
- if (data->physical_size == (uoff_t)-1)
+ if (data->physical_size == (uoff_t)-1) {
(void)index_mail_get_physical_size(_mail, size_r);
- if (data->physical_size == (uoff_t)-1) {
- old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
- if (mail_get_stream(_mail, NULL, NULL, &input) < 0)
+ if (data->physical_size != (uoff_t)-1) {
+ *size_r = data->physical_size;
+ return 0;
+ }
+ }
+
+ if (IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE) &&
+ data->stream == NULL) {
+ /* trust RFC822.SIZE to be correct */
+ if (imapc_mail_fetch(_mail, MAIL_FETCH_PHYSICAL_SIZE) < 0)
return -1;
- i_stream_seek(data->stream, old_offset);
+ if (data->physical_size == (uoff_t)-1) {
+ if (imapc_mail_failed(_mail, "RFC822.SIZE") < 0)
+ return -1;
+ /* assume that the server never returns RFC822.SIZE
+ for this mail (see BODY[] failure handling) */
+ data->physical_size = 0;
+ }
+ *size_r = data->physical_size;
+ return 0;
+ }
- ret = i_stream_get_size(data->stream, TRUE,
- &data->physical_size);
- if (ret <= 0) {
- i_assert(ret != 0);
- mail_storage_set_critical(_mail->box->storage,
- "imapc: stat(%s) failed: %m",
- i_stream_get_name(data->stream));
- return -1;
- }
+ old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
+ if (mail_get_stream(_mail, NULL, NULL, &input) < 0)
+ return -1;
+ i_stream_seek(data->stream, old_offset);
+
+ ret = i_stream_get_size(data->stream, TRUE,
+ &data->physical_size);
+ if (ret <= 0) {
+ i_assert(ret != 0);
+ mail_storage_set_critical(_mail->box->storage,
+ "imapc: stat(%s) failed: %m",
+ i_stream_get_name(data->stream));
+ return -1;
}
*size_r = data->physical_size;
return 0;
@@ -200,6 +221,7 @@
static void index_mail_update_access_parts(struct index_mail *mail)
{
struct mail *_mail = &mail->mail.mail;
+ struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
struct index_mail_data *data = &mail->data;
struct mailbox_header_lookup_ctx *header_ctx;
time_t date;
@@ -208,7 +230,8 @@
if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0)
(void)index_mail_get_received_date(_mail, &date);
if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) {
- if (index_mail_get_physical_size(_mail, &size) < 0)
+ if (index_mail_get_physical_size(_mail, &size) < 0 &&
+ !IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE))
data->access_part |= READ_HDR | READ_BODY;
}
diff -r 87cd04f35f82 -r 6a8b78450202 src/lib-storage/index/imapc/imapc-settings.c
--- a/src/lib-storage/index/imapc/imapc-settings.c Fri Mar 30 05:11:09 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-settings.c Fri Mar 30 05:20:08 2012 +0300
@@ -25,6 +25,7 @@
DEF(SET_STR, imapc_ssl_ca_dir),
DEF(SET_BOOL, imapc_ssl_verify),
+ DEF(SET_STR, imapc_features),
DEF(SET_STR, imapc_rawlog_dir),
DEF(SET_STR, ssl_crypto_device),
@@ -43,6 +44,7 @@
.imapc_ssl_ca_dir = "",
.imapc_ssl_verify = TRUE,
+ .imapc_features = "",
.imapc_rawlog_dir = "",
.ssl_crypto_device = ""
};
@@ -67,6 +69,43 @@
}
/* <settings checks> */
+struct imapc_feature_list {
+ const char *name;
+ enum imapc_features num;
+};
+
+static const struct imapc_feature_list imapc_feature_list[] = {
+ { "rfc822.size", IMAPC_FEATURE_RFC822_SIZE },
+ { NULL, 0 }
+};
+
+static int
+imapc_settings_parse_features(struct imapc_settings *set,
+ const char **error_r)
+{
+ enum imapc_features features = 0;
+ const struct imapc_feature_list *list;
+ const char *const *str;
+
+ str = t_strsplit_spaces(set->imapc_features, " ,");
+ for (; *str != NULL; str++) {
+ list = imapc_feature_list;
+ for (; list->name != NULL; list++) {
+ if (strcasecmp(*str, list->name) == 0) {
+ features |= list->num;
+ break;
+ }
+ }
+ if (list->name == NULL) {
+ *error_r = t_strdup_printf("imapc_features: "
+ "Unknown feature: %s", *str);
+ return -1;
+ }
+ }
+ set->parsed_features = features;
+ return 0;
+}
+
static bool imapc_settings_check(void *_set, pool_t pool ATTR_UNUSED,
const char **error_r)
{
@@ -85,5 +124,7 @@
return FALSE;
}
#endif
+ if (imapc_settings_parse_features(set, error_r) < 0)
+ return FALSE;
return TRUE;
}
diff -r 87cd04f35f82 -r 6a8b78450202 src/lib-storage/index/imapc/imapc-settings.h
--- a/src/lib-storage/index/imapc/imapc-settings.h Fri Mar 30 05:11:09 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-settings.h Fri Mar 30 05:20:08 2012 +0300
@@ -1,6 +1,12 @@
#ifndef IMAPC_SETTINGS_H
#define IMAPC_SETTINGS_H
+/* <settings checks> */
+enum imapc_features {
+ IMAPC_FEATURE_RFC822_SIZE = 0x01
+};
+/* </settings checks> */
+
struct imapc_settings {
const char *imapc_host;
unsigned int imapc_port;
@@ -13,8 +19,11 @@
const char *imapc_ssl_ca_dir;
bool imapc_ssl_verify;
+ const char *imapc_features;
const char *imapc_rawlog_dir;
const char *ssl_crypto_device;
+
+ enum imapc_features parsed_features;
};
const struct setting_parser_info *imapc_get_setting_parser_info(void);
diff -r 87cd04f35f82 -r 6a8b78450202 src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h Fri Mar 30 05:11:09 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.h Fri Mar 30 05:20:08 2012 +0300
@@ -2,6 +2,7 @@
#define IMAPC_STORAGE_H
#include "index-storage.h"
+#include "imapc-settings.h"
#define IMAPC_STORAGE_NAME "imapc"
#define IMAPC_INDEX_PREFIX "dovecot.index"
@@ -28,6 +29,11 @@
imapc_mailbox_callback_t *callback;
};
+#define IMAPC_HAS_FEATURE(mstorage, feature) \
+ (((mstorage)->set->parsed_features & feature) != 0)
+#define IMAPC_BOX_HAS_FEATURE(mbox, feature) \
+ (((mbox)->storage->set->parsed_features & feature) != 0)
+
struct imapc_storage {
struct mail_storage storage;
const struct imapc_settings *set;
More information about the dovecot-cvs
mailing list