From: Timo Sirainen Date: Wed, 23 Jun 2004 18:33:22 +0000 (+0300) Subject: Added a framework for getting POP3 UIDL strings from mail-storage. The X-Git-Tag: 1.1.alpha1~3868 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33d63688ed8b26dc333e3c2edbfb2fe6e412604d;p=thirdparty%2Fdovecot%2Fcore.git Added a framework for getting POP3 UIDL strings from mail-storage. The default still is uidvalidity.uid. Added beginnings of overriding it from X-UIDL header in mbox. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache.h b/src/lib-index/mail-cache.h index 5317883b0d..c285098a73 100644 --- a/src/lib-index/mail-cache.h +++ b/src/lib-index/mail-cache.h @@ -42,6 +42,7 @@ enum mail_cache_field { 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 | @@ -55,7 +56,8 @@ enum mail_cache_field { 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 diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 5b6eb48cca..f80533e9c7 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -499,6 +499,13 @@ const char *index_mail_get_special(struct mail *_mail, 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; @@ -510,9 +517,17 @@ void index_mail_init(struct index_transaction_context *t, 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; diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index d5c5b4eb5b..df5bf1386c 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -23,7 +23,7 @@ struct index_mail_data { 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; @@ -57,6 +57,7 @@ struct index_mail { 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; diff --git a/src/lib-storage/index/mbox/mbox-sync-parse.c b/src/lib-storage/index/mbox/mbox-sync-parse.c index 73fbd33073..9f61f5192d 100644 --- a/src/lib-storage/index/mbox/mbox-sync-parse.c +++ b/src/lib-storage/index/mbox/mbox-sync-parse.c @@ -223,6 +223,21 @@ static int parse_x_uid(struct mbox_sync_mail_context *ctx, 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) { @@ -259,6 +274,7 @@ static struct header_func header_funcs[] = { { "X-Keywords", parse_x_keywords }, { "X-Status", parse_x_status }, { "X-UID", parse_x_uid }, + { "X-UIDL", parse_x_uidl }, { NULL, NULL } }; diff --git a/src/lib-storage/index/mbox/mbox-sync-private.h b/src/lib-storage/index/mbox/mbox-sync-private.h index ca172c3967..6cd6000878 100644 --- a/src/lib-storage/index/mbox/mbox-sync-private.h +++ b/src/lib-storage/index/mbox/mbox-sync-private.h @@ -54,7 +54,7 @@ struct mbox_sync_mail_context { 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; @@ -80,7 +80,7 @@ struct mbox_sync_context { 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; diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index ba72ccdfeb..241c2cf9e3 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -198,6 +198,8 @@ mbox_sync_read_next_mail(struct mbox_sync_context *sync_ctx, 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); @@ -403,9 +405,10 @@ mbox_sync_update_from_offset(struct mbox_sync_context *sync_ctx, } 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; @@ -416,6 +419,12 @@ static int mbox_sync_update_index(struct mbox_sync_context *sync_ctx, 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; @@ -785,7 +794,7 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx, } 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; } @@ -1129,6 +1138,7 @@ int mbox_sync(struct index_mailbox *ibox, int last_commit, 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; @@ -1227,6 +1237,7 @@ int mbox_sync(struct index_mailbox *ibox, int last_commit, ret = -1; } + str_free(sync_ctx.uidl); str_free(sync_ctx.header); str_free(sync_ctx.from_line); buffer_free(sync_ctx.mails); diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 675bf709ea..ed69821e8e 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -65,21 +65,22 @@ enum mail_sort_type { }; 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 { diff --git a/src/pop3/client.c b/src/pop3/client.c index e0a93a5c3a..4f05a1ce1a 100644 --- a/src/pop3/client.c +++ b/src/pop3/client.c @@ -51,8 +51,7 @@ static int init_mailbox(struct client *client) 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; @@ -60,7 +59,6 @@ static int init_mailbox(struct client *client) client->messages_count = status.messages; client->deleted_size = 0; - client->uidvalidity = status.uidvalidity; if (client->messages_count == 0) return TRUE; diff --git a/src/pop3/client.h b/src/pop3/client.h index ee7d019b96..4721c1ee08 100644 --- a/src/pop3/client.h +++ b/src/pop3/client.h @@ -17,7 +17,6 @@ struct client { unsigned int messages_count; unsigned int deleted_count; - unsigned int uidvalidity; uoff_t *message_sizes; uoff_t total_size; uoff_t deleted_size; diff --git a/src/pop3/commands.c b/src/pop3/commands.c index bea8e2c8f7..8a86d68560 100644 --- a/src/pop3/commands.c +++ b/src/pop3/commands.c @@ -366,6 +366,7 @@ static void list_uids(struct client *client, unsigned int message) 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) @@ -396,9 +397,9 @@ static void list_uids(struct client *client, unsigned int message) 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; }