MAIL_CACHE_BODYSTRUCTURE = 0x01000000,
MAIL_CACHE_ENVELOPE = 0x00800000,
MAIL_CACHE_MESSAGEPART = 0x00400000,
+ MAIL_CACHE_UID_STRING = 0x00200000,
MAIL_CACHE_FIXED_MASK = MAIL_CACHE_INDEX_FLAGS |
MAIL_CACHE_SENT_DATE |
MAIL_CACHE_LOCATION |
MAIL_CACHE_BODY |
MAIL_CACHE_BODYSTRUCTURE |
- MAIL_CACHE_ENVELOPE,
+ MAIL_CACHE_ENVELOPE |
+ MAIL_CACHE_UID_STRING,
MAIL_CACHE_BODYSTRUCTURE_MASK = MAIL_CACHE_BODY |
MAIL_CACHE_BODYSTRUCTURE |
MAIL_CACHE_MESSAGEPART
return data->envelope;
case MAIL_FETCH_FROM_ENVELOPE:
return NULL;
+ case MAIL_FETCH_UID_STRING:
+ if (data->uid_string == NULL) {
+ data->uid_string =
+ p_strdup_printf(mail->pool, "%u.%u",
+ mail->uid_validity, _mail->uid);
+ }
+ return data->uid_string;
default:
i_unreached();
return NULL;
enum mail_fetch_field wanted_fields,
const char *const wanted_headers[])
{
+ const struct mail_index_header *hdr;
+ int ret;
+
mail->mail = *t->ibox->mail_interface;
mail->mail.box = &t->ibox->box;
+ ret = mail_index_get_header(t->ibox->view, &hdr);
+ i_assert(ret == 0);
+
+ mail->uid_validity = hdr->uid_validity;
+
mail->pool = pool_alloconly_create("index_mail", 16384);
mail->ibox = t->ibox;
mail->trans = t;
int header_save_idx;
struct message_part *parts;
- const char *envelope, *body, *bodystructure;
+ const char *envelope, *body, *bodystructure, *uid_string;
struct message_part_envelope_data *envelope_data;
uint32_t seq;
struct index_transaction_context *trans;
unsigned int expunge_counter;
buffer_t *header_buf;
+ uint32_t uid_validity;
enum mail_fetch_field wanted_fields;
const char *const *wanted_headers;
return TRUE;
}
+static int parse_x_uidl(struct mbox_sync_mail_context *ctx,
+ struct message_header_line *hdr)
+{
+ size_t i;
+
+ for (i = 0; i < hdr->full_value_len; i++) {
+ if (IS_LWSP_LF(hdr->full_value[i]))
+ break;
+ }
+
+ str_truncate(ctx->uidl, 0);
+ str_append_n(ctx->uidl, hdr->full_value, i);
+ return TRUE;
+}
+
static int parse_content_length(struct mbox_sync_mail_context *ctx,
struct message_header_line *hdr)
{
{ "X-Keywords", parse_x_keywords },
{ "X-Status", parse_x_status },
{ "X-UID", parse_x_uid },
+ { "X-UIDL", parse_x_uidl },
{ NULL, NULL }
};
uoff_t from_offset, hdr_offset, body_offset;
size_t header_first_change, header_last_change;
- string_t *header;
+ string_t *header, *uidl;
uoff_t content_length;
struct mail_index_transaction *t;
const struct mail_index_header *hdr;
- string_t *header, *from_line;
+ string_t *header, *uidl, *from_line;
/* header state: */
uint32_t base_uid_validity, base_uid_last;
mail_ctx->sync_ctx = sync_ctx;
mail_ctx->seq = ++sync_ctx->seq;
mail_ctx->header = sync_ctx->header;
+ mail_ctx->uidl = sync_ctx->uidl;
+ str_truncate(mail_ctx->uidl, 0);
mail_ctx->from_offset =
istream_raw_mbox_get_start_offset(sync_ctx->input);
}
static int mbox_sync_update_index(struct mbox_sync_context *sync_ctx,
- struct mbox_sync_mail *mail,
+ struct mbox_sync_mail_context *mail_ctx,
const struct mail_index_record *rec)
{
+ struct mbox_sync_mail *mail = &mail_ctx->mail;
keywords_mask_t idx_keywords;
uint8_t idx_flags, mbox_flags;
mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
MODIFY_REPLACE, mbox_flags,
mail->keywords);
+ if (str_len(mail_ctx->uidl) > 0) {
+ /*FIXME:mail_cache_add(sync_ctx->cache_trans,
+ MAIL_CACHE_UID_STRING,
+ str_data(mail_ctx->uidl),
+ str_len(mail_ctx->uidl));*/
+ }
} else {
/* see if flags changed */
idx_flags = rec->flags;
}
if (!expunged && !mail_ctx->pseudo) {
- if (mbox_sync_update_index(sync_ctx, &mail_ctx->mail,
+ if (mbox_sync_update_index(sync_ctx, mail_ctx,
rec) < 0)
return -1;
}
sync_ctx.ibox = ibox;
sync_ctx.from_line = str_new(default_pool, 256);
sync_ctx.header = str_new(default_pool, 4096);
+ sync_ctx.uidl = str_new(default_pool, 128);
sync_ctx.lock_id = lock_id;
sync_ctx.index_sync_ctx = index_sync_ctx;
ret = -1;
}
+ str_free(sync_ctx.uidl);
str_free(sync_ctx.header);
str_free(sync_ctx.from_line);
buffer_free(sync_ctx.mails);
};
enum mail_fetch_field {
- MAIL_FETCH_FLAGS = 0x0001,
- MAIL_FETCH_MESSAGE_PARTS = 0x0002,
+ MAIL_FETCH_FLAGS = 0x00000001,
+ MAIL_FETCH_MESSAGE_PARTS = 0x00000002,
- MAIL_FETCH_RECEIVED_DATE = 0x0004,
- MAIL_FETCH_DATE = 0x0008,
- MAIL_FETCH_SIZE = 0x0010,
+ MAIL_FETCH_RECEIVED_DATE = 0x00000004,
+ MAIL_FETCH_DATE = 0x00000008,
+ MAIL_FETCH_SIZE = 0x00000010,
- MAIL_FETCH_STREAM_HEADER = 0x0020,
- MAIL_FETCH_STREAM_BODY = 0x0040,
+ MAIL_FETCH_STREAM_HEADER = 0x00000020,
+ MAIL_FETCH_STREAM_BODY = 0x00000040,
/* specials: */
- MAIL_FETCH_IMAP_BODY = 0x1000,
- MAIL_FETCH_IMAP_BODYSTRUCTURE = 0x2000,
- MAIL_FETCH_IMAP_ENVELOPE = 0x4000,
- MAIL_FETCH_FROM_ENVELOPE = 0x8000
+ MAIL_FETCH_IMAP_BODY = 0x00001000,
+ MAIL_FETCH_IMAP_BODYSTRUCTURE = 0x00002000,
+ MAIL_FETCH_IMAP_ENVELOPE = 0x00004000,
+ MAIL_FETCH_FROM_ENVELOPE = 0x00008000,
+ MAIL_FETCH_UID_STRING = 0x00010000
};
enum mailbox_sync_flags {
search_arg.type = SEARCH_ALL;
for (i = 0; i < 2; i++) {
- if (mailbox_get_status(client->mailbox,
- STATUS_MESSAGES | STATUS_UIDVALIDITY,
+ if (mailbox_get_status(client->mailbox, STATUS_MESSAGES,
&status) < 0) {
client_send_storage_error(client);
return FALSE;
client->messages_count = status.messages;
client->deleted_size = 0;
- client->uidvalidity = status.uidvalidity;
if (client->messages_count == 0)
return TRUE;
unsigned int messages_count;
unsigned int deleted_count;
- unsigned int uidvalidity;
uoff_t *message_sizes;
uoff_t total_size;
uoff_t deleted_size;
struct mailbox_transaction_context *t;
struct mail_search_context *ctx;
struct mail *mail;
+ const char *uid_str;
int found = FALSE;
if (client->messages_count == 0 && message == 0)
continue;
}
- client_send_line(client, message == 0 ?
- "%u %u.%u" : "+OK %u %u.%u",
- mail->seq, client->uidvalidity, mail->uid);
+ uid_str = mail->get_special(mail, MAIL_FETCH_UID_STRING);
+ client_send_line(client, message == 0 ? "%u %s" : "+OK %u %s",
+ mail->seq, uid_str);
found = TRUE;
}