#include "imap-arg.h"
#include "imap-date.h"
#include "imap-quote.h"
+#include "imap-bodystructure.h"
#include "imap-resp-code.h"
#include "imapc-client.h"
#include "imapc-mail.h"
str_append(str, mbox->guid_fetch_field_name);
str_append_c(str, ' ');
}
+ if ((fields & MAIL_FETCH_IMAP_BODY) != 0)
+ str_append(str, "BODY ");
+ if ((fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0)
+ str_append(str, "BODYSTRUCTURE ");
if ((fields & MAIL_FETCH_STREAM_BODY) != 0) {
if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_ZIMBRA_WORKAROUNDS))
data->physical_size == (uoff_t)-1 &&
IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE))
fields |= MAIL_FETCH_PHYSICAL_SIZE | MAIL_FETCH_VIRTUAL_SIZE;
+ if ((data->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
+ data->body == NULL &&
+ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE))
+ fields |= MAIL_FETCH_IMAP_BODY;
+ if ((data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
+ data->bodystructure == NULL &&
+ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE))
+ fields |= MAIL_FETCH_IMAP_BODYSTRUCTURE;
if ((data->wanted_fields & MAIL_FETCH_GUID) != 0 &&
data->guid == NULL && mbox->guid_fetch_field_name != NULL)
fields |= MAIL_FETCH_GUID;
return FALSE;
fields &= ~MAIL_FETCH_GUID;
}
+ if ((fields & MAIL_FETCH_IMAP_BODY) != 0) {
+ if (imail->imail.data.body == NULL)
+ return FALSE;
+ fields &= ~MAIL_FETCH_IMAP_BODY;
+ }
+ if ((fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
+ if (imail->imail.data.bodystructure == NULL)
+ return FALSE;
+ fields &= ~MAIL_FETCH_IMAP_BODYSTRUCTURE;
+ }
if ((fields & (MAIL_FETCH_STREAM_HEADER |
MAIL_FETCH_STREAM_BODY)) != 0) {
if (imail->imail.data.stream == NULL)
i_stream_destroy(&input);
}
+static const char *
+imapc_args_to_bodystructure(struct imapc_mail *mail,
+ const struct imap_arg *list_arg, bool extended)
+{
+ const struct imap_arg *args;
+ struct message_part *parts = NULL;
+ const char *ret, *error;
+ pool_t pool;
+
+ if (!imap_arg_get_list(list_arg, &args)) {
+ mail_storage_set_critical(mail->imail.mail.mail.box->storage,
+ "imapc: Server sent invalid BODYSTRUCTURE parameters");
+ return NULL;
+ }
+
+ pool = pool_alloconly_create("imap bodystructure", 1024);
+ if (imap_bodystructure_parse_args(args, pool, &parts, &error) < 0) {
+ mail_storage_set_critical(mail->imail.mail.mail.box->storage,
+ "imapc: Server sent invalid BODYSTRUCTURE: %s", error);
+ ret = NULL;
+ } else {
+ string_t *str = t_str_new(128);
+ imap_bodystructure_write(parts, str, extended);
+ ret = p_strdup(mail->imail.mail.data_pool, str_c(str));
+ }
+ pool_unref(&pool);
+ return ret;
+}
+
void imapc_mail_fetch_update(struct imapc_mail *mail,
const struct imapc_untagged_reply *reply,
const struct imap_arg *args)
imap_parse_datetime(value, &t, &tz))
mail->imail.data.received_date = t;
match = TRUE;
+ } else if (strcasecmp(key, "BODY") == 0) {
+ if (IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE)) {
+ mail->imail.data.body =
+ imapc_args_to_bodystructure(mail, &args[i+1], FALSE);
+ }
+ match = TRUE;
+ } else if (strcasecmp(key, "BODYSTRUCTURE") == 0) {
+ if (IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE)) {
+ mail->imail.data.bodystructure =
+ imapc_args_to_bodystructure(mail, &args[i+1], TRUE);
+ }
+ match = TRUE;
} else if (strcasecmp(key, "RFC822.SIZE") == 0) {
if (imap_arg_get_atom(&args[i+1], &value) &&
str_to_uoff(value, &size) == 0 &&
struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
struct index_mail_data *data = &mail->data;
struct mailbox_header_lookup_ctx *header_ctx;
+ const char *str;
time_t date;
uoff_t size;
}
if ((data->wanted_fields & MAIL_FETCH_GUID) != 0)
(void)imapc_mail_get_cached_guid(_mail);
+ if ((data->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0)
+ (void)index_mail_get_cached_body(mail, &str);
+ if ((data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0)
+ (void)index_mail_get_cached_bodystructure(mail, &str);
if (data->access_part == 0 && data->wanted_headers != NULL &&
!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_HEADERS)) {
*value_r = p_strdup_printf(imail->mail.data_pool, "GmailId%llx",
(unsigned long long)num);
return 0;
+ case MAIL_FETCH_IMAP_BODY:
+ if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE))
+ break;
+
+ if (index_mail_get_cached_body(imail, value_r))
+ return 0;
+ if (imapc_mail_fetch(_mail, field, NULL) < 0)
+ return -1;
+ if (imail->data.body == NULL) {
+ (void)imapc_mail_failed(_mail, "BODY");
+ return -1;
+ }
+ *value_r = imail->data.body;
+ return 0;
+ case MAIL_FETCH_IMAP_BODYSTRUCTURE:
+ if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_BODYSTRUCTURE))
+ break;
+
+ if (index_mail_get_cached_bodystructure(imail, value_r))
+ return 0;
+ if (imapc_mail_fetch(_mail, field, NULL) < 0)
+ return -1;
+ if (imail->data.bodystructure == NULL) {
+ (void)imapc_mail_failed(_mail, "BODYSTRUCTURE");
+ return -1;
+ }
+ *value_r = imail->data.bodystructure;
+ return 0;
default:
break;
}