Mercurial > dovecot > core-2.2
changeset 2504:98f6057f27a1 HEAD
Added mail.get_physical_size().
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 28 Aug 2004 13:32:16 +0300 |
parents | 2946fa696774 |
children | 847759a0ff75 |
files | src/imap/imap-fetch-body.c src/imap/imap-sort.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-mail.h src/lib-storage/index/index-search.c src/lib-storage/index/maildir/maildir-mail.c src/lib-storage/index/mbox/mbox-mail.c src/lib-storage/mail-storage.h src/lib-storage/proxy-mail.c src/pop3/client.c src/pop3/commands.c |
diffstat | 11 files changed, 157 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/imap-fetch-body.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/imap/imap-fetch-body.c Sat Aug 28 13:32:16 2004 +0300 @@ -759,7 +759,7 @@ { uoff_t size; - size = mail->get_size(mail); + size = mail->get_virtual_size(mail); if (size == (uoff_t)-1) return -1; @@ -858,7 +858,7 @@ } if (strcmp(arg+6, ".SIZE") == 0) { - ctx->fetch_data |= MAIL_FETCH_SIZE; + ctx->fetch_data |= MAIL_FETCH_VIRTUAL_SIZE; imap_fetch_add_handler(ctx, fetch_rfc822_size, NULL); return TRUE; }
--- a/src/imap/imap-sort.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/imap/imap-sort.c Sat Aug 28 13:32:16 2004 +0300 @@ -143,7 +143,7 @@ if (ctx->cache_mask & MAIL_SORT_DATE) fields |= MAIL_FETCH_DATE; if (ctx->cache_mask & MAIL_SORT_SIZE) - fields |= MAIL_FETCH_SIZE; + fields |= MAIL_FETCH_VIRTUAL_SIZE; /* @UNSAFE */ i_assert(MAX_WANTED_HEADERS > 4); @@ -349,7 +349,7 @@ } if (ctx->common_mask & MAIL_SORT_SIZE) { - size = mail->get_size(mail); + size = mail->get_virtual_size(mail); if (size != ctx->last_size) { ctx->last_size = size; changed = TRUE; @@ -425,7 +425,7 @@ if (ctx->common_mask & MAIL_SORT_SIZE) size = ctx->last_size; else - size = mail->get_size(mail); + size = mail->get_virtual_size(mail); memcpy(buf + pos, &size, sizeof(size)); pos += sizeof(size); } @@ -554,7 +554,7 @@ i_assert(type == MAIL_SORT_SIZE); - return mail->get_size(mail); + return mail->get_virtual_size(mail); } /* use memcpy() to avoid any alignment problems */
--- a/src/lib-storage/index/index-mail.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/index/index-mail.c Sat Aug 28 13:32:16 2004 +0300 @@ -21,6 +21,8 @@ sizeof(time_t), 0 }, { "size.virtual", 0, MAIL_CACHE_FIELD_FIXED_SIZE, sizeof(uoff_t), 0 }, + { "size.physical", 0, MAIL_CACHE_FIELD_FIXED_SIZE, + sizeof(uoff_t), 0 }, { "imap.body", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, { "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, { "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, @@ -125,6 +127,12 @@ return index_mail_get_cached_uoff_t(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE); } +static uoff_t index_mail_get_cached_physical_size(struct index_mail *mail) +{ + return index_mail_get_cached_uoff_t(mail, + MAIL_CACHE_PHYSICAL_FULL_SIZE); +} + time_t index_mail_get_cached_received_date(struct index_mail *mail) { time_t t; @@ -251,36 +259,56 @@ } data->body_size = data->parts->body_size; data->body_size_set = TRUE; - data->size = data->parts->header_size.virtual_size + + data->virtual_size = data->parts->header_size.virtual_size + data->body_size.virtual_size; + data->physical_size = data->parts->header_size.physical_size + + data->body_size.physical_size; } return data->parts != NULL; } -uoff_t index_mail_get_size(struct mail *_mail) +uoff_t index_mail_get_virtual_size(struct mail *_mail) { struct index_mail *mail = (struct index_mail *) _mail; struct index_mail_data *data = &mail->data; struct message_size hdr_size, body_size; - if (data->size != (uoff_t)-1) - return data->size; + if (data->virtual_size != (uoff_t)-1) + return data->virtual_size; - data->size = index_mail_get_cached_virtual_size(mail); - if (data->size != (uoff_t)-1) - return data->size; + data->virtual_size = index_mail_get_cached_virtual_size(mail); + if (data->virtual_size != (uoff_t)-1) + return data->virtual_size; if (get_cached_msgpart_sizes(mail)) - return data->size; + return data->virtual_size; if (_mail->get_stream(_mail, &hdr_size, &body_size) == NULL) return (uoff_t)-1; mail_cache_add(mail->trans->cache_trans, mail->data.seq, cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx, - &data->size, sizeof(data->size)); - return data->size; + &data->virtual_size, sizeof(data->virtual_size)); + return data->virtual_size; +} + +uoff_t index_mail_get_physical_size(struct mail *_mail) +{ + struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail_data *data = &mail->data; + + if (data->physical_size != (uoff_t)-1) + return data->physical_size; + + data->physical_size = index_mail_get_cached_physical_size(mail); + if (data->physical_size != (uoff_t)-1) + return data->physical_size; + + if (get_cached_msgpart_sizes(mail)) + return data->physical_size; + + return (uoff_t)-1; } static void parse_bodystructure_part_header(struct message_part *part, @@ -295,7 +323,6 @@ static void index_mail_parse_body(struct index_mail *mail, int need_parts) { struct index_mail_data *data = &mail->data; - enum mail_cache_record_flag cache_flags; enum mail_cache_decision_type decision; buffer_t *buffer; const void *buf_data; @@ -398,8 +425,10 @@ } if (data->hdr_size_set && data->body_size_set) { - data->size = data->hdr_size.virtual_size + + data->virtual_size = data->hdr_size.virtual_size + data->body_size.virtual_size; + data->physical_size = data->hdr_size.physical_size + + data->body_size.physical_size; } i_stream_seek(data->stream, 0); @@ -615,7 +644,8 @@ data->rec = rec; data->seq = seq; - data->size = (uoff_t)-1; + data->virtual_size = (uoff_t)-1; + data->physical_size = (uoff_t)-1; data->received_date = data->sent_date.time = (time_t)-1; t_push(); @@ -633,8 +663,10 @@ data->bodystructure = index_mail_get_cached_string(mail, MAIL_CACHE_BODYSTRUCTURE); } - if (mail->wanted_fields & MAIL_FETCH_SIZE) - data->size = index_mail_get_cached_virtual_size(mail); + if (mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) + data->virtual_size = index_mail_get_cached_virtual_size(mail); + if (mail->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) + data->physical_size = index_mail_get_cached_physical_size(mail); if (mail->wanted_fields & MAIL_FETCH_DATE) get_cached_sent_date(mail, &data->sent_date);
--- a/src/lib-storage/index/index-mail.h Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/index/index-mail.h Sat Aug 28 13:32:16 2004 +0300 @@ -11,6 +11,7 @@ MAIL_CACHE_SENT_DATE, MAIL_CACHE_RECEIVED_DATE, MAIL_CACHE_VIRTUAL_FULL_SIZE, + MAIL_CACHE_PHYSICAL_FULL_SIZE, /* variable sized field */ MAIL_CACHE_BODY, @@ -54,7 +55,7 @@ struct index_mail_data { struct mail_full_flags flags; time_t date, received_date; - uoff_t size; + uoff_t virtual_size, physical_size; struct mail_sent_date sent_date; struct index_mail_line parse_line; @@ -130,7 +131,8 @@ const struct message_part *index_mail_get_parts(struct mail *_mail); time_t index_mail_get_received_date(struct mail *_mail); time_t index_mail_get_date(struct mail *_mail, int *timezone); -uoff_t index_mail_get_size(struct mail *_mail); +uoff_t index_mail_get_virtual_size(struct mail *mail); +uoff_t index_mail_get_physical_size(struct mail *mail); struct istream *index_mail_init_stream(struct index_mail *mail, struct message_size *hdr_size, struct message_size *body_size);
--- a/src/lib-storage/index/index-search.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/index/index-search.c Sat Aug 28 13:32:16 2004 +0300 @@ -236,7 +236,7 @@ /* sizes */ case SEARCH_SMALLER: case SEARCH_LARGER: - virtual_size = ctx->mail->get_size(ctx->mail); + virtual_size = ctx->mail->get_virtual_size(ctx->mail); if (virtual_size == (uoff_t)-1) return -1;
--- a/src/lib-storage/index/maildir/maildir-mail.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Sat Aug 28 13:32:16 2004 +0300 @@ -102,21 +102,21 @@ return data->received_date; } -static uoff_t maildir_mail_get_size(struct mail *_mail) +static uoff_t maildir_mail_get_virtual_size(struct mail *_mail) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; const char *fname, *p; uoff_t virtual_size; enum maildir_uidlist_rec_flag flags; - if (data->size != (uoff_t)-1) - return data->size; + if (data->virtual_size != (uoff_t)-1) + return data->virtual_size; - if ((mail->wanted_fields & MAIL_FETCH_SIZE) == 0) { - data->size = index_mail_get_cached_virtual_size(mail); - if (data->size != (uoff_t)-1) - return data->size; + if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) == 0) { + data->virtual_size = index_mail_get_cached_virtual_size(mail); + if (data->virtual_size != (uoff_t)-1) + return data->virtual_size; } fname = maildir_uidlist_lookup(mail->ibox->uidlist, @@ -142,7 +142,53 @@ } } - return index_mail_get_size(_mail); + return index_mail_get_virtual_size(_mail); +} + +static uoff_t maildir_mail_get_physical_size(struct mail *_mail) +{ + struct index_mail *mail = (struct index_mail *)_mail; + struct index_mail_data *data = &mail->data; + struct stat st; + const char *fname, *p; + uoff_t size; + enum maildir_uidlist_rec_flag flags; + + size = index_mail_get_physical_size(_mail); + if (size != (uoff_t)-1) + return size; + + fname = maildir_uidlist_lookup(mail->ibox->uidlist, + mail->mail.uid, &flags); + if (fname == NULL) + return (uoff_t)-1; + + /* size can be included in filename */ + p = strstr(fname, ",S="); + if (p != NULL) { + p += 3; + size = 0; + while (*p >= '0' && *p <= '9') { + size = size * 10 + (*p - '0'); + p++; + } + + if (*p != ':' && *p != ',' && *p != '\0') + size = (uoff_t)-1; + } + + if (size == (uoff_t)-1) { + if (maildir_file_do(mail->ibox, mail->mail.uid, + do_stat, &st) <= 0) + return (uoff_t)-1; + size = st.st_size; + } + + mail_cache_add(mail->trans->cache_trans, mail->data.seq, + MAIL_CACHE_PHYSICAL_FULL_SIZE, &size, sizeof(size)); + data->physical_size = size; + return size; + } static struct istream *maildir_mail_get_stream(struct mail *_mail, @@ -172,7 +218,8 @@ index_mail_get_parts, maildir_mail_get_received_date, index_mail_get_date, - maildir_mail_get_size, + maildir_mail_get_virtual_size, + maildir_mail_get_physical_size, index_mail_get_header, index_mail_get_headers, maildir_mail_get_stream,
--- a/src/lib-storage/index/mbox/mbox-mail.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-mail.c Sat Aug 28 13:32:16 2004 +0300 @@ -111,6 +111,24 @@ return index_mail_get_special(_mail, field); } +static uoff_t mbox_mail_get_physical_size(struct mail *_mail) +{ + struct index_mail *mail = (struct index_mail *)_mail; + struct index_mail_data *data = &mail->data; + struct istream *stream; + uoff_t hdr_offset, body_offset, body_size; + + /* our header size varies, so don't do any caching */ + stream = mail->ibox->mbox_stream; + hdr_offset = istream_raw_mbox_get_header_offset(stream); + body_offset = istream_raw_mbox_get_body_offset(stream); + body_size = istream_raw_mbox_get_body_size(stream, (uoff_t)-1); + + data->physical_size = (body_offset - hdr_offset) + body_size; + return data->physical_size; + +} + static struct istream *mbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, struct message_size *body_size) @@ -147,7 +165,8 @@ index_mail_get_parts, mbox_mail_get_received_date, index_mail_get_date, - index_mail_get_size, + index_mail_get_virtual_size, + mbox_mail_get_physical_size, index_mail_get_header, index_mail_get_headers, mbox_mail_get_stream,
--- a/src/lib-storage/mail-storage.h Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/mail-storage.h Sat Aug 28 13:32:16 2004 +0300 @@ -70,10 +70,11 @@ MAIL_FETCH_RECEIVED_DATE = 0x00000004, MAIL_FETCH_DATE = 0x00000008, - MAIL_FETCH_SIZE = 0x00000010, + MAIL_FETCH_VIRTUAL_SIZE = 0x00000010, + MAIL_FETCH_PHYSICAL_SIZE = 0x00000020, - MAIL_FETCH_STREAM_HEADER = 0x00000020, - MAIL_FETCH_STREAM_BODY = 0x00000040, + MAIL_FETCH_STREAM_HEADER = 0x00000040, + MAIL_FETCH_STREAM_BODY = 0x00000080, /* specials: */ MAIL_FETCH_IMAP_BODY = 0x00001000, @@ -366,7 +367,10 @@ time_t (*get_date)(struct mail *mail, int *timezone); /* Get the full virtual size of mail (IMAP RFC822.SIZE). Returns (uoff_t)-1 if error occured */ - uoff_t (*get_size)(struct mail *mail); + uoff_t (*get_virtual_size)(struct mail *mail); + /* Get the full physical size of mail. + Returns (uoff_t)-1 if error occured */ + uoff_t (*get_physical_size)(struct mail *mail); /* Get value for single header field */ const char *(*get_header)(struct mail *mail, const char *field);
--- a/src/lib-storage/proxy-mail.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/lib-storage/proxy-mail.c Sat Aug 28 13:32:16 2004 +0300 @@ -31,11 +31,18 @@ return p->mail->get_date(p->mail, timezone); } -static uoff_t _get_size(struct mail *mail) +static uoff_t _get_virtual_size(struct mail *mail) { struct proxy_mail *p = (struct proxy_mail *) mail; - return p->mail->get_size(p->mail); + return p->mail->get_virtual_size(p->mail); +} + +static uoff_t _get_physical_size(struct mail *mail) +{ + struct proxy_mail *p = (struct proxy_mail *) mail; + + return p->mail->get_physical_size(p->mail); } static const char *_get_header(struct mail *mail, const char *field) @@ -97,7 +104,8 @@ pm->get_parts = _get_parts; pm->get_received_date = _get_received_date; pm->get_date = _get_date; - pm->get_size = _get_size; + pm->get_virtual_size = _get_virtual_size; + pm->get_physical_size = _get_physical_size; pm->get_header = _get_header; pm->get_headers = _get_headers; pm->get_stream = _get_stream;
--- a/src/pop3/client.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/pop3/client.c Sat Aug 28 13:32:16 2004 +0300 @@ -82,7 +82,7 @@ t = mailbox_transaction_begin(client->mailbox, FALSE); ctx = mailbox_search_init(t, NULL, &search_arg, NULL, - MAIL_FETCH_SIZE, NULL); + MAIL_FETCH_VIRTUAL_SIZE, NULL); if (ctx == NULL) { client_send_storage_error(client); mailbox_transaction_rollback(t); @@ -93,7 +93,7 @@ client->deleted_size = 0; failed = FALSE; while ((mail = mailbox_search_next(ctx)) != NULL) { - uoff_t size = mail->get_size(mail); + uoff_t size = mail->get_virtual_size(mail); if (size == (uoff_t)-1) { failed = TRUE;
--- a/src/pop3/commands.c Sat Aug 28 13:31:37 2004 +0300 +++ b/src/pop3/commands.c Sat Aug 28 13:32:16 2004 +0300 @@ -186,7 +186,7 @@ t = mailbox_transaction_begin(box, FALSE); ctx = mailbox_search_init(t, NULL, &search_arg, NULL, - MAIL_FETCH_SIZE, NULL); + MAIL_FETCH_VIRTUAL_SIZE, NULL); if (ctx == NULL) { mailbox_transaction_rollback(t); return FALSE;