[dovecot-cvs] dovecot/src/lib-storage/index index-transaction.c,
NONE, 1.1 Makefile.am, 1.12, 1.13 index-fetch.c, 1.52,
1.53 index-mail-headers.c, 1.17, 1.18 index-mail.c, 1.24,
1.25 index-mail.h, 1.10, 1.11 index-mailbox-check.c, 1.7,
1.8 index-search.c, 1.82, 1.83 index-status.c, 1.26,
1.27 index-storage.c, 1.41, 1.42 index-storage.h, 1.53,
1.54 index-sync.c, 1.27, 1.28 index-copy.c, 1.29,
NONE index-expunge.c, 1.20, NONE index-expunge.h, 1.1,
NONE index-messageset.c, 1.21, NONE index-messageset.h, 1.8,
NONE index-update-flags.c, 1.26, NONE
cras at procontrol.fi
cras at procontrol.fi
Tue Apr 27 23:25:57 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/lib-mail mail-types.h, NONE,
1.1 Makefile.am, 1.7, 1.8 message-parser.c, 1.50,
1.51 message-parser.h, 1.23, 1.24
- Next message: [dovecot-cvs] dovecot/src/lib-storage/register Makefile.am,1.1,1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv29236/src/lib-storage/index
Modified Files:
Makefile.am index-fetch.c index-mail-headers.c index-mail.c
index-mail.h index-mailbox-check.c index-search.c
index-status.c index-storage.c index-storage.h index-sync.c
Added Files:
index-transaction.c
Removed Files:
index-copy.c index-expunge.c index-expunge.h
index-messageset.c index-messageset.h index-update-flags.c
Log Message:
importing new index code. mbox still broken.
--- NEW FILE: index-transaction.c ---
/* Copyright (C) 2003 Timo Sirainen */
#include "lib.h"
#include "index-storage.h"
static void index_transaction_free(struct index_transaction_context *t)
{
mail_index_view_unlock(t->ibox->view);
if (t->fetch_mail.pool != NULL)
index_mail_deinit(&t->fetch_mail);
i_free(t);
}
int index_transaction_commit(struct mailbox_transaction_context *_t)
{
struct index_transaction_context *t =
(struct index_transaction_context *)_t;
uint32_t seq;
uoff_t offset;
int ret;
if (t->cache_trans != NULL)
(void)mail_cache_transaction_commit(t->cache_trans);
ret = mail_index_transaction_commit(t->trans, &seq, &offset);
if (ret < 0)
mail_storage_set_index_error(t->ibox);
t->ibox->commit_log_file_seq = seq;
t->ibox->commit_log_file_offset = offset;
index_transaction_free(t);
return ret;
}
void index_transaction_rollback(struct mailbox_transaction_context *_t)
{
struct index_transaction_context *t =
(struct index_transaction_context *)_t;
mail_index_transaction_rollback(t->trans);
index_transaction_free(t);
}
Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/Makefile.am,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- Makefile.am 18 Aug 2003 03:24:37 -0000 1.12
+++ Makefile.am 27 Apr 2004 20:25:54 -0000 1.13
@@ -10,21 +10,16 @@
-I$(top_srcdir)/src/lib-storage
libstorage_index_a_SOURCES = \
- index-copy.c \
- index-expunge.c \
index-fetch.c \
index-mail.c \
index-mail-headers.c \
index-mailbox-check.c \
- index-messageset.c \
index-search.c \
index-status.c \
index-storage.c \
index-sync.c \
- index-update-flags.c
+ index-transaction.c
noinst_HEADERS = \
- index-expunge.h \
index-mail.h \
- index-messageset.h \
index-storage.h
Index: index-fetch.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-fetch.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- index-fetch.c 26 Oct 2003 20:13:15 -0000 1.52
+++ index-fetch.c 27 Apr 2004 20:25:54 -0000 1.53
@@ -1,62 +1,46 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
-#include "ostream.h"
-#include "str.h"
-#include "mail-index.h"
-#include "mail-modifylog.h"
-#include "mail-custom-flags.h"
#include "index-storage.h"
-#include "index-messageset.h"
#include "index-mail.h"
-static struct mail *
-fetch_record(struct index_mailbox *ibox, struct mail_index_record *rec,
- unsigned int idx_seq, enum mail_fetch_field wanted_fields)
+struct mail *
+index_storage_fetch(struct mailbox_transaction_context *_t, uint32_t seq,
+ enum mail_fetch_field wanted_fields)
{
- if (ibox->fetch_mail.pool != NULL)
- index_mail_deinit(&ibox->fetch_mail);
+ struct index_transaction_context *t =
+ (struct index_transaction_context *)_t;
+ const struct mail_index_record *rec;
- index_mail_init(ibox, &ibox->fetch_mail, wanted_fields, NULL);
- if (index_mail_next(&ibox->fetch_mail, rec, idx_seq, FALSE) <= 0)
+ if (mail_index_lookup(t->ibox->view, seq, &rec) < 0) {
+ mail_storage_set_index_error(t->ibox);
return NULL;
+ }
- return &ibox->fetch_mail.mail;
-}
-
-struct mail *index_storage_fetch_uid(struct mailbox *box, unsigned int uid,
- enum mail_fetch_field wanted_fields)
-{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_index_record *rec;
- unsigned int seq;
+ if (rec == NULL)
+ return NULL;
- i_assert(ibox->index->lock_type != MAIL_LOCK_UNLOCK);
+ if (t->fetch_mail.pool != NULL)
+ index_mail_deinit(&t->fetch_mail);
- rec = ibox->index->lookup_uid_range(ibox->index, uid, uid, &seq);
- if (rec == NULL)
+ index_mail_init(t, &t->fetch_mail, wanted_fields, NULL);
+ if (index_mail_next(&t->fetch_mail, rec, seq, FALSE) <= 0)
return NULL;
- return fetch_record(ibox, rec, seq, wanted_fields);
+ return &t->fetch_mail.mail;
}
-struct mail *index_storage_fetch_seq(struct mailbox *box, unsigned int seq,
- enum mail_fetch_field wanted_fields)
+int index_storage_get_uids(struct mailbox *box,
+ uint32_t uid1, uint32_t uid2,
+ uint32_t *seq1_r, uint32_t *seq2_r)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_index_record *rec;
- unsigned int expunges_before;
-
- i_assert(ibox->index->lock_type != MAIL_LOCK_UNLOCK);
-
- if (mail_modifylog_seq_get_expunges(ibox->index->modifylog, seq, seq,
- &expunges_before) == NULL)
- return NULL;
+ struct index_mailbox *ibox = (struct index_mailbox *)box;
- seq -= expunges_before;
- rec = ibox->index->lookup(ibox->index, seq);
- if (rec == NULL)
- return NULL;
+ if (mail_index_lookup_uid_range(ibox->view, uid1, uid2,
+ seq1_r, seq2_r) < 0) {
+ mail_storage_set_index_error(ibox);
+ return -1;
+ }
- return fetch_record(ibox, rec, seq, wanted_fields);
+ return 0;
}
Index: index-mail-headers.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail-headers.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-mail-headers.c 21 Oct 2003 13:50:09 -0000 1.17
+++ index-mail-headers.c 27 Apr 2004 20:25:54 -0000 1.18
@@ -39,6 +39,7 @@
#include "buffer.h"
#include "str.h"
#include "message-date.h"
+#include "message-parser.h"
#include "imap-envelope.h"
#include "imap-bodystructure.h"
#include "index-storage.h"
@@ -140,7 +141,7 @@
return data;
}
-static int find_wanted_headers(struct mail_cache *cache,
+static int find_wanted_headers(struct mail_cache_view *cache_view,
const char *const wanted_headers[])
{
const char *const *headers, *const *tmp;
@@ -154,7 +155,7 @@
ret = -1;
for (i = MAIL_CACHE_HEADERS_COUNT-1; i >= 0; i--) {
- headers = mail_cache_get_header_fields(cache, i);
+ headers = mail_cache_get_header_fields(cache_view, i);
if (headers == NULL)
continue;
@@ -185,7 +186,7 @@
{
int idx;
- idx = find_wanted_headers(mail->ibox->index->cache, wanted_headers);
+ idx = find_wanted_headers(mail->ibox->cache_view, wanted_headers);
if (idx < 0)
return -1;
@@ -433,7 +434,7 @@
data->header_stream = istream;
} else {
str = mail_cache_lookup_string_field(
- mail->ibox->index->cache, data->rec,
+ mail->ibox->cache_view, data->seq,
mail_cache_header_fields[idx]);
if (str == NULL) {
/* broken - we expected the header to exist */
@@ -446,10 +447,10 @@
str, strlen(str));
}
- idx_headers = mail_cache_get_header_fields(mail->ibox->index->cache,
+ idx_headers = mail_cache_get_header_fields(mail->ibox->cache_view,
idx);
if (idx_headers == NULL) {
- mail_cache_set_corrupted(mail->ibox->index->cache,
+ mail_cache_set_corrupted(mail->ibox->cache,
"Headers %d names not found", idx);
t_pop();
return FALSE;
@@ -485,13 +486,14 @@
int index_mail_parse_headers(struct index_mail *mail)
{
- struct mail_cache *cache = mail->ibox->index->cache;
struct index_mail_data *data = &mail->data;
const char *str, *const *headers;
int idx, max;
- if (!index_mail_open_stream(mail, 0))
- return FALSE;
+ if (data->stream == NULL) {
+ if (mail->mail.get_stream(&mail->mail, NULL, NULL) == NULL)
+ return FALSE;
+ }
if (mail->data.header_data == NULL)
mail->data.header_data = str_new(mail->pool, 4096);
@@ -508,8 +510,9 @@
/* add all cached headers to beginning of header_data */
idx = data->header_data_cached; max = idx-1;
for (; idx < MAIL_CACHE_HEADERS_COUNT; idx++) {
- str = mail_cache_lookup_string_field(cache, data->rec,
- mail_cache_header_fields[idx]);
+ str = mail_cache_lookup_string_field(
+ mail->ibox->cache_view, mail->data.seq,
+ mail_cache_header_fields[idx]);
if (str == NULL)
continue;
@@ -522,7 +525,8 @@
/* make sure we cache everything */
for (idx = MAIL_CACHE_HEADERS_COUNT-1; idx >= 0; idx--) {
- headers = mail_cache_get_header_fields(cache, idx);
+ headers = mail_cache_get_header_fields(
+ mail->ibox->cache_view, idx);
if (headers != NULL)
break;
}
@@ -537,8 +541,10 @@
if (max >= 0) {
/* now we'll have to set value_idx for all headers that
are already cached */
- if (!parse_cached_headers(mail, max))
+ if (!parse_cached_headers(mail, max)) {
+ /* FIXME: handle better */
return FALSE;
+ }
}
/* it's possible that we're parsing headers without wanting
@@ -593,8 +599,10 @@
idx = mail_find_wanted_headers(mail, arr);
if (idx >= 0) {
- if (!parse_cached_headers(mail, idx))
- return NULL;
+ if (!parse_cached_headers(mail, idx)) {
+ /* broken cache, parse again */
+ idx = -1;
+ }
}
}
@@ -647,7 +655,7 @@
}
for (i = data->header_data_cached; i <= idx; i++) {
str = mail_cache_lookup_string_field(
- mail->ibox->index->cache, data->rec,
+ mail->ibox->cache_view, data->seq,
mail_cache_header_fields[i]);
if (str == NULL)
continue;
@@ -679,14 +687,14 @@
void index_mail_headers_init(struct index_mail *mail)
{
- struct mail_cache *cache = mail->ibox->index->cache;
+ struct mail_cache_view *cache_view = mail->ibox->cache_view;
int idx = -2, idx2 = -2;
if (mail->wanted_headers != NULL && *mail->wanted_headers != NULL)
- idx = find_wanted_headers(cache, mail->wanted_headers);
+ idx = find_wanted_headers(cache_view, mail->wanted_headers);
if (idx != -1 && (mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE))
- idx2 = find_wanted_headers(cache, imap_envelope_headers);
+ idx2 = find_wanted_headers(cache_view, imap_envelope_headers);
mail->wanted_headers_idx = idx == -1 || idx2 == -1 ? -1 :
idx > idx2 ? idx : idx2;
@@ -735,12 +743,12 @@
}
}
-static int find_unused_header_idx(struct mail_cache *cache)
+static int find_unused_header_idx(struct mail_cache_view *cache_view)
{
int i;
for (i = 0; i < MAIL_CACHE_HEADERS_COUNT; i++) {
- if (mail_cache_get_header_fields(cache, i) == NULL)
+ if (mail_cache_get_header_fields(cache_view, i) == NULL)
return i;
}
@@ -761,21 +769,21 @@
accessing headers from same message. index_mails should probably be
shared.. */
headers = cached_header_get_names(mail);
- idx = find_wanted_headers(mail->ibox->index->cache, headers);
+ idx = find_wanted_headers(mail->ibox->cache_view, headers);
if (idx >= 0) {
/* all headers found */
if (idx != mail->data.header_save_idx) {
- mail_cache_set_corrupted(mail->ibox->index->cache,
+ mail_cache_set_corrupted(mail->ibox->cache,
"Duplicated header names list (%d and %d)",
idx, mail->data.header_save_idx);
}
} else {
/* there's some new headers */
- idx = find_unused_header_idx(mail->ibox->index->cache);
+ idx = find_unused_header_idx(mail->ibox->cache_view);
if (idx < 0)
return;
- if (!mail_cache_set_header_fields(mail->ibox->trans_ctx,
+ if (!mail_cache_set_header_fields(mail->trans->cache_trans,
idx, headers))
return;
}
@@ -784,7 +792,7 @@
len = str_len(mail->data.header_data) -
data->header_data_uncached_offset;
- mail_cache_add(mail->ibox->trans_ctx, data->rec,
+ mail_cache_add(mail->trans->cache_trans, data->seq,
mail_cache_header_fields[idx], str, len+1);
data->header_save = FALSE;
}
Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- index-mail.c 26 Oct 2003 18:05:42 -0000 1.24
+++ index-mail.c 27 Apr 2004 20:25:54 -0000 1.25
@@ -6,15 +6,14 @@
#include "str.h"
#include "message-date.h"
#include "message-part-serialize.h"
+#include "message-parser.h"
#include "imap-bodystructure.h"
#include "imap-envelope.h"
-#include "mail-custom-flags.h"
#include "mail-cache.h"
#include "index-storage.h"
-#include "index-expunge.h"
#include "index-mail.h"
-static int index_mail_parse_body(struct index_mail *mail);
+static void index_mail_parse_body(struct index_mail *mail);
static struct message_part *get_cached_parts(struct index_mail *mail)
{
@@ -24,12 +23,12 @@
size_t part_size;
if ((mail->data.cached_fields & MAIL_CACHE_MESSAGEPART) == 0) {
- mail_cache_mark_missing(mail->ibox->index->cache,
+ mail_cache_mark_missing(mail->ibox->cache_view,
MAIL_CACHE_MESSAGEPART);
return NULL;
}
- if (!mail_cache_lookup_field(mail->ibox->index->cache, mail->data.rec,
+ if (!mail_cache_lookup_field(mail->ibox->cache_view, mail->data.seq,
MAIL_CACHE_MESSAGEPART,
&part_data, &part_size)) {
/* unexpected - must be an error */
@@ -39,7 +38,7 @@
part = message_part_deserialize(mail->pool, part_data, part_size,
&error);
if (part == NULL) {
- mail_cache_set_corrupted(mail->ibox->index->cache,
+ mail_cache_set_corrupted(mail->ibox->cache,
"Corrupted cached message_part data (%s)", error);
return NULL;
}
@@ -56,50 +55,48 @@
return part;
}
-static char *get_cached_string(struct index_mail *mail,
- enum mail_cache_field field)
+char *index_mail_get_cached_string(struct index_mail *mail,
+ enum mail_cache_field field)
{
const char *ret;
if ((mail->data.cached_fields & field) == 0) {
- mail_cache_mark_missing(mail->ibox->index->cache, field);
+ mail_cache_mark_missing(mail->ibox->cache_view, field);
return NULL;
}
- ret = mail_cache_lookup_string_field(mail->ibox->index->cache,
- mail->data.rec, field);
+ ret = mail_cache_lookup_string_field(mail->ibox->cache_view,
+ mail->data.seq, field);
return p_strdup(mail->pool, ret);
}
-static uoff_t get_cached_uoff_t(struct index_mail *mail,
- enum mail_cache_field field)
+uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
+ enum mail_cache_field field)
{
uoff_t uoff;
- if (!mail_cache_copy_fixed_field(mail->ibox->index->cache,
- mail->data.rec, field,
- &uoff, sizeof(uoff))) {
- mail_cache_mark_missing(mail->ibox->index->cache, field);
+ if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
+ field, &uoff, sizeof(uoff))) {
+ mail_cache_mark_missing(mail->ibox->cache_view, field);
uoff = (uoff_t)-1;
}
return uoff;
}
-static uoff_t get_cached_virtual_size(struct index_mail *mail)
+uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail)
{
- return get_cached_uoff_t(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE);
+ return index_mail_get_cached_uoff_t(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE);
}
-static time_t get_cached_received_date(struct index_mail *mail)
+time_t index_mail_get_cached_received_date(struct index_mail *mail)
{
time_t t;
- if (!mail_cache_copy_fixed_field(mail->ibox->index->cache,
- mail->data.rec,
+ if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
MAIL_CACHE_RECEIVED_DATE,
&t, sizeof(t))) {
- mail_cache_mark_missing(mail->ibox->index->cache,
+ mail_cache_mark_missing(mail->ibox->cache_view,
MAIL_CACHE_RECEIVED_DATE);
t = (time_t)-1;
}
@@ -110,10 +107,10 @@
static void get_cached_sent_date(struct index_mail *mail,
struct mail_sent_date *sent_date)
{
- if (!mail_cache_copy_fixed_field(mail->ibox->index->cache,
- mail->data.rec, MAIL_CACHE_SENT_DATE,
+ if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
+ MAIL_CACHE_SENT_DATE,
sent_date, sizeof(*sent_date))) {
- mail_cache_mark_missing(mail->ibox->index->cache,
+ mail_cache_mark_missing(mail->ibox->cache_view,
MAIL_CACHE_SENT_DATE);
sent_date->time = (time_t)-1;
@@ -123,16 +120,16 @@
int index_mail_cache_transaction_begin(struct index_mail *mail)
{
- if (mail->ibox->trans_ctx != NULL)
+ if (mail->trans->cache_trans != NULL)
return TRUE;
- if (mail_cache_transaction_begin(mail->ibox->index->cache, TRUE,
- &mail->ibox->trans_ctx) <= 0)
+ if (mail_cache_transaction_begin(mail->ibox->cache_view, TRUE,
+ mail->trans->trans,
+ &mail->trans->cache_trans) <= 0)
return FALSE;
- mail->data.cached_fields =
- mail_cache_get_fields(mail->ibox->index->cache,
- mail->data.rec);
+ mail->data.cached_fields = mail_cache_get_fields(mail->ibox->cache_view,
+ mail->data.seq);
return TRUE;
}
@@ -157,60 +154,33 @@
void index_mail_cache_add(struct index_mail *mail, enum mail_cache_field field,
const void *data, size_t size)
{
- struct index_mailbox *ibox = mail->ibox;
-
if (!index_mail_cache_can_add(mail, field))
return;
- if (!mail_cache_add(ibox->trans_ctx, mail->data.rec,
+ if (!mail_cache_add(mail->trans->cache_trans, mail->data.seq,
field, data, size))
- mail_cache_transaction_rollback(ibox->trans_ctx);
+ mail_cache_transaction_rollback(mail->trans->cache_trans);
mail->data.cached_fields |= field;
}
-int index_mail_open_stream(struct index_mail *mail, uoff_t position)
-{
- struct index_mail_data *data = &mail->data;
- int deleted;
-
- if (data->stream == NULL) {
- data->stream = mail->ibox->index->
- open_mail(mail->ibox->index, data->rec,
- &data->received_date, &deleted);
- data->deleted = deleted;
-
- if (data->stream == NULL)
- return FALSE;
-
- if (data->received_date != (time_t)-1) {
- index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
- &data->received_date,
- sizeof(data->received_date));
- }
- }
-
- i_stream_seek(mail->data.stream, position);
- return TRUE;
-}
-
-static const struct mail_full_flags *get_flags(struct mail *_mail)
+const struct mail_full_flags *index_mail_get_flags(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
- data->flags.flags = data->rec->msg_flags;
- data->flags.custom_flags =
+ data->flags.flags = data->rec->flags;
+ /*FIXME:data->flags.custom_flags =
mail_custom_flags_list_get(mail->ibox->index->custom_flags);
data->flags.custom_flags_count = MAIL_CUSTOM_FLAGS_COUNT;
if (data->rec->uid >= mail->ibox->index->first_recent_uid)
- data->flags.flags |= MAIL_RECENT;
+ data->flags.flags |= MAIL_RECENT;*/
return &data->flags;
}
-static const struct message_part *get_parts(struct mail *_mail)
+const struct message_part *index_mail_get_parts(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
@@ -228,37 +198,12 @@
if (!index_mail_parse_headers(mail))
return NULL;
}
- if (!index_mail_parse_body(mail))
- return NULL;
+ index_mail_parse_body(mail);
return data->parts;
}
-static time_t get_received_date(struct mail *_mail)
-{
- struct index_mail *mail = (struct index_mail *) _mail;
- struct index_mail_data *data = &mail->data;
-
- if (data->received_date != (time_t)-1)
- return data->received_date;
-
- if ((mail->wanted_fields & MAIL_FETCH_RECEIVED_DATE) == 0) {
- data->received_date = get_cached_received_date(mail);
- if (data->received_date != (time_t)-1)
- return data->received_date;
- }
-
- data->received_date = mail->ibox->index->
- get_received_date(mail->ibox->index, mail->data.rec);
- if (data->received_date != (time_t)-1) {
- index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
- &data->received_date,
- sizeof(data->received_date));
- }
- return data->received_date;
-}
-
-static time_t get_date(struct mail *_mail, int *timezone)
+time_t index_mail_get_date(struct mail *_mail, int *timezone)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
@@ -302,7 +247,7 @@
if (data->parts == NULL) {
if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0)
- (void)get_parts(&mail->mail);
+ (void)index_mail_get_parts(&mail->mail);
else
data->parts = get_cached_parts(mail);
}
@@ -319,7 +264,7 @@
return data->parts != NULL;
}
-static uoff_t get_size(struct mail *_mail)
+uoff_t index_mail_get_size(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
@@ -329,7 +274,7 @@
return data->size;
if ((mail->wanted_fields & MAIL_FETCH_SIZE) == 0) {
- data->size = get_cached_virtual_size(mail);
+ data->size = index_mail_get_cached_virtual_size(mail);
if (data->size != (uoff_t)-1)
return data->size;
}
@@ -352,7 +297,7 @@
imap_bodystructure_parse_header(pool, part, hdr);
}
-static int index_mail_parse_body(struct index_mail *mail)
+static void index_mail_parse_body(struct index_mail *mail)
{
struct index_mail_data *data = &mail->data;
enum mail_index_record_flag index_flags;
@@ -379,7 +324,7 @@
data->body_size_set = TRUE;
if (mail->mail.has_nuls || mail->mail.has_no_nuls)
- return TRUE;
+ return;
/* we know the NULs now, update them */
if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
@@ -391,19 +336,19 @@
}
if (!index_mail_cache_transaction_begin(mail))
- return TRUE;
+ return;
/* update index_flags */
- index_flags = mail_cache_get_index_flags(mail->ibox->index->cache,
- mail->data.rec);
+ index_flags = mail_cache_get_index_flags(mail->ibox->cache_view,
+ mail->data.seq);
if (mail->mail.has_nuls)
index_flags |= MAIL_INDEX_FLAG_HAS_NULS;
else
index_flags |= MAIL_INDEX_FLAG_HAS_NO_NULS;
- if (!mail_cache_update_index_flags(mail->ibox->index->cache,
- mail->data.rec, index_flags))
- return FALSE;
+ if (!mail_cache_update_index_flags(mail->ibox->cache_view,
+ mail->data.seq, index_flags))
+ return;
if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) {
t_push();
@@ -416,19 +361,15 @@
buf_data, buf_size);
t_pop();
}
- return TRUE;
}
-static struct istream *get_stream(struct mail *_mail,
- struct message_size *hdr_size,
- struct message_size *body_size)
+struct istream *index_mail_init_stream(struct index_mail *_mail,
+ struct message_size *hdr_size,
+ struct message_size *body_size)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
- if (!index_mail_open_stream(mail, 0))
- return NULL;
-
if (hdr_size != NULL || body_size != NULL)
(void)get_msgpart_sizes(mail);
@@ -442,10 +383,8 @@
}
if (body_size != NULL) {
- if (!data->body_size_set) {
- if (!index_mail_parse_body(mail))
- return NULL;
- }
+ if (!data->body_size_set)
+ index_mail_parse_body(mail);
*body_size = data->body_size;
}
@@ -459,28 +398,30 @@
return data->stream;
}
-static const char *get_special(struct mail *_mail, enum mail_fetch_field field)
+const char *index_mail_get_special(struct mail *_mail,
+ enum mail_fetch_field field)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
- struct mail_cache *cache = mail->ibox->index->cache;
+ struct mail_cache *cache = mail->ibox->cache;
enum mail_cache_field cache_field;
char *str;
switch (field) {
case MAIL_FETCH_IMAP_BODY:
if ((data->cached_fields & MAIL_CACHE_BODY) &&
- data->body == NULL)
- data->body = get_cached_string(mail, MAIL_CACHE_BODY);
+ data->body == NULL) {
+ data->body = index_mail_get_cached_string(mail,
+ MAIL_CACHE_BODY);
+ }
if (data->body != NULL)
return data->body;
/* fall through */
case MAIL_FETCH_IMAP_BODYSTRUCTURE:
if ((data->cached_fields & MAIL_CACHE_BODYSTRUCTURE) &&
data->bodystructure == NULL) {
- data->bodystructure =
- get_cached_string(mail,
- MAIL_CACHE_BODYSTRUCTURE);
+ data->bodystructure = index_mail_get_cached_string(mail,
+ MAIL_CACHE_BODYSTRUCTURE);
}
if (data->bodystructure != NULL) {
@@ -514,8 +455,7 @@
parse_bodystructure_header,
mail->pool);
} else {
- if (!index_mail_parse_body(mail))
- return NULL;
+ index_mail_parse_body(mail);
}
t_push();
@@ -548,39 +488,21 @@
}
}
-static struct mail index_mail = {
- 0, 0, 0, 0, 0,
-
- get_flags,
- get_parts,
- get_received_date,
- get_date,
- get_size,
- index_mail_get_header,
- index_mail_get_headers,
- get_stream,
- get_special,
- index_storage_update_flags,
- index_storage_expunge
-};
-
-void index_mail_init(struct index_mailbox *ibox, struct index_mail *mail,
+void index_mail_init(struct index_transaction_context *t,
+ struct index_mail *mail,
enum mail_fetch_field wanted_fields,
const char *const wanted_headers[])
{
- mail->mail = index_mail;
- mail->mail.box = &ibox->box;
+ mail->mail = *t->ibox->mail_interface;
+ mail->mail.box = &t->ibox->box;
mail->pool = pool_alloconly_create("index_mail", 16384);
- mail->ibox = ibox;
+ mail->ibox = t->ibox;
+ mail->trans = t;
mail->wanted_fields = wanted_fields;
mail->wanted_headers = wanted_headers;
- mail->expunge_counter = ibox->index->expunge_counter;
index_mail_headers_init(mail);
-
- if (ibox->mail_init != NULL)
- ibox->mail_init(mail);
}
static void index_mail_close(struct index_mail *mail)
@@ -591,48 +513,49 @@
index_mail_headers_close(mail);
}
-int index_mail_next(struct index_mail *mail, struct mail_index_record *rec,
- unsigned int idx_seq, int delay_open)
+int index_mail_next(struct index_mail *mail,
+ const struct mail_index_record *rec,
+ uint32_t seq, int delay_open)
{
- struct mail_index *index = mail->ibox->index;
struct index_mail_data *data = &mail->data;
enum mail_index_record_flag index_flags;
int ret, open_mail;
- i_assert(mail->expunge_counter == index->expunge_counter);
-
t_push();
index_mail_close(mail);
memset(data, 0, sizeof(*data));
p_clear(mail->pool);
- data->cached_fields = mail_cache_get_fields(index->cache, rec);
+ data->cached_fields =
+ mail_cache_get_fields(mail->ibox->cache_view, seq);
index_flags = (data->cached_fields & MAIL_CACHE_INDEX_FLAGS) == 0 ? 0 :
- mail_cache_get_index_flags(index->cache, rec);
+ mail_cache_get_index_flags(mail->ibox->cache_view, seq);
mail->mail.has_nuls = (index_flags & MAIL_INDEX_FLAG_HAS_NULS) != 0;
mail->mail.has_no_nuls =
(index_flags & MAIL_INDEX_FLAG_HAS_NO_NULS) != 0;
data->rec = rec;
- data->idx_seq = idx_seq;
+ data->seq = seq;
data->size = (uoff_t)-1;
data->received_date = data->sent_date.time = (time_t)-1;
/* if some wanted fields are cached, get them */
if (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS)
data->parts = get_cached_parts(mail);
- if (mail->wanted_fields & MAIL_FETCH_IMAP_BODY)
- data->body = get_cached_string(mail, MAIL_CACHE_BODY);
+ if (mail->wanted_fields & MAIL_FETCH_IMAP_BODY) {
+ data->body =
+ index_mail_get_cached_string(mail, MAIL_CACHE_BODY);
+ }
if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) ||
((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) &&
data->body == NULL)) {
- data->bodystructure =
- get_cached_string(mail, MAIL_CACHE_BODYSTRUCTURE);
+ data->bodystructure = index_mail_get_cached_string(mail,
+ MAIL_CACHE_BODYSTRUCTURE);
}
if (mail->wanted_fields & MAIL_FETCH_SIZE)
- data->size = get_cached_virtual_size(mail);
+ data->size = index_mail_get_cached_virtual_size(mail);
if (mail->wanted_fields & MAIL_FETCH_DATE)
get_cached_sent_date(mail, &data->sent_date);
@@ -662,14 +585,15 @@
index_mail_headers_init_next(mail);
if ((open_mail || data->parse_header) && !delay_open) {
- if (!index_mail_open_stream(mail, 0))
+ if (mail->mail.get_stream(&mail->mail, NULL, NULL) == NULL)
ret = data->deleted ? 0 : -1;
else
ret = 1;
} else {
if (mail->wanted_fields & MAIL_FETCH_RECEIVED_DATE) {
/* check this only after open_mail() */
- data->received_date = get_cached_received_date(mail);
+ data->received_date =
+ index_mail_get_cached_received_date(mail);
}
ret = 1;
}
@@ -694,3 +618,40 @@
pool_unref(mail->pool);
memset(mail, 0, sizeof(*mail));
}
+
+int index_mail_update_flags(struct mail *mail,
+ const struct mail_full_flags *flags,
+ enum modify_type modify_type)
+{
+ struct index_mail *imail = (struct index_mail *)mail;
+ enum mail_flags modify_flags;
+ custom_flags_mask_t custom_flags;
+
+ /* \Recent can't be changed */
+ modify_flags = flags->flags & ~MAIL_RECENT;
+
+ /*if (!index_mailbox_fix_custom_flags(ibox, &modify_flags,
+ flags->custom_flags,
+ flags->custom_flags_count))
+ return FALSE;*/
+
+ memset(custom_flags, 0, sizeof(custom_flags));
+ mail_index_update_flags(imail->trans->trans, mail->seq, modify_type,
+ flags->flags, custom_flags);
+
+ /*if (mail_custom_flags_has_changes(ibox->index->custom_flags)) {
+ storage->callbacks->new_custom_flags(&ibox->box,
+ mail_custom_flags_list_get(ibox->index->custom_flags),
+ MAIL_CUSTOM_FLAGS_COUNT, storage->callback_context);
+ }*/
+
+ return 0;
+}
+
+int index_mail_expunge(struct mail *mail)
+{
+ struct index_mail *imail = (struct index_mail *)mail;
+
+ mail_index_expunge(imail->trans->trans, mail->seq);
+ return 0;
+}
Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- index-mail.h 8 Sep 2003 02:24:29 -0000 1.10
+++ index-mail.h 27 Apr 2004 20:25:54 -0000 1.11
@@ -3,6 +3,7 @@
#include "message-size.h"
#include "mail-cache.h"
+#include "mail-storage-private.h"
struct message_header_line;
@@ -25,8 +26,8 @@
const char *envelope, *body, *bodystructure;
struct message_part_envelope_data *envelope_data;
- struct mail_index_record *rec;
- unsigned int idx_seq;
+ uint32_t seq;
+ const struct mail_index_record *rec;
struct istream *stream;
struct message_size hdr_size, body_size;
@@ -53,6 +54,7 @@
pool_t pool;
struct index_mailbox *ibox;
+ struct index_transaction_context *trans;
unsigned int expunge_counter;
buffer_t *header_buf;
@@ -61,11 +63,13 @@
int wanted_headers_idx;
};
-void index_mail_init(struct index_mailbox *ibox, struct index_mail *mail,
+void index_mail_init(struct index_transaction_context *t,
+ struct index_mail *mail,
enum mail_fetch_field wanted_fields,
const char *const wanted_headers[]);
-int index_mail_next(struct index_mail *mail, struct mail_index_record *rec,
- unsigned int idx_seq, int delay_open);
+int index_mail_next(struct index_mail *mail,
+ const struct mail_index_record *rec,
+ uint32_t seq, int delay_open);
void index_mail_deinit(struct index_mail *mail);
void index_mail_parse_header_init(struct index_mail *mail,
@@ -78,7 +82,6 @@
void index_mail_cache_add(struct index_mail *mail, enum mail_cache_field field,
const void *data, size_t size);
-int index_mail_open_stream(struct index_mail *mail, uoff_t position);
int index_mail_parse_headers(struct index_mail *mail);
void index_mail_headers_init(struct index_mail *mail);
@@ -89,4 +92,26 @@
struct istream *index_mail_get_headers(struct mail *_mail,
const char *const minimum_fields[]);
+const struct mail_full_flags *index_mail_get_flags(struct mail *_mail);
+const struct message_part *index_mail_get_parts(struct mail *_mail);
+time_t index_mail_get_date(struct mail *_mail, int *timezone);
+uoff_t index_mail_get_size(struct mail *_mail);
+struct istream *index_mail_init_stream(struct index_mail *mail,
+ struct message_size *hdr_size,
+ struct message_size *body_size);
+const char *index_mail_get_special(struct mail *_mail,
+ enum mail_fetch_field field);
+
+int index_mail_update_flags(struct mail *mail,
+ const struct mail_full_flags *flags,
+ enum modify_type modify_type);
+int index_mail_expunge(struct mail *mail);
+
+char *index_mail_get_cached_string(struct index_mail *mail,
+ enum mail_cache_field field);
+uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
+ enum mail_cache_field field);
+uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail);
+time_t index_mail_get_cached_received_date(struct index_mail *mail);
+
#endif
Index: index-mailbox-check.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mailbox-check.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- index-mailbox-check.c 24 Aug 2003 12:59:08 -0000 1.7
+++ index-mailbox-check.c 27 Apr 2004 20:25:54 -0000 1.8
@@ -5,6 +5,8 @@
#include "index-storage.h"
#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <sys/stat.h>
static void check_timeout(void *context)
Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- index-search.c 26 Oct 2003 20:13:15 -0000 1.82
+++ index-search.c 27 Apr 2004 20:25:54 -0000 1.83
@@ -7,12 +7,10 @@
#include "message-date.h"
#include "message-body-search.h"
#include "message-header-search.h"
+#include "message-parser.h"
#include "imap-date.h"
#include "index-storage.h"
-#include "index-messageset.h"
#include "index-mail.h"
-#include "mail-custom-flags.h"
-#include "mail-modifylog.h"
#include "mail-search.h"
#include <stdlib.h>
@@ -21,12 +19,14 @@
#define TXT_UNKNOWN_CHARSET "[BADCHARSET] Unknown charset"
#define TXT_INVALID_SEARCH_KEY "Invalid search key"
-struct mail_search_context {
+struct index_search_context {
+ struct mail_search_context mail_ctx;
+ struct index_transaction_context *trans;
struct index_mailbox *ibox;
char *charset;
struct mail_search_arg *args;
- struct messageset_context *msgset_ctx;
+ uint32_t seq1, seq2;
struct index_mail imail;
struct mail *mail;
@@ -37,7 +37,7 @@
};
struct search_header_context {
- struct mail_search_context *index_context;
+ struct index_search_context *index_context;
struct mail_search_arg *args;
struct message_header_line *hdr;
@@ -47,70 +47,17 @@
};
struct search_body_context {
- struct mail_search_context *index_ctx;
+ struct index_search_context *index_ctx;
struct istream *input;
const struct message_part *part;
};
-static int msgset_contains(const char *set, unsigned int match_num,
- unsigned int max_num)
+static int seqset_contains(struct mail_search_seqset *set, uint32_t seq)
{
- unsigned int num, num2;
-
- while (*set != '\0') {
- if (*set == '*') {
- set++;
- num = max_num;
- } else {
- num = 0;
- while (*set >= '0' && *set <= '9') {
- num = num*10 + (*set-'0');
- set++;
- }
-
- if (num == 0)
- return FALSE;
- }
-
- if (*set == ',' || *set == '\0') {
- if (num == match_num)
- return TRUE;
- if (*set == '\0')
- return FALSE;
- } else if (*set == ':') {
- set++;
-
- if (*set == '*') {
- set++;
-
- if (match_num >= num && num <= max_num)
- return TRUE;
- } else {
- num2 = 0;
- while (*set >= '0' && *set <= '9') {
- num2 = num2*10 + (*set-'0');
- set++;
- }
-
- if (num2 == 0)
- return FALSE;
-
- if (num > num2) {
- /* swap, as specified by RFC-3501 */
- unsigned int temp = num;
- num = num2;
- num2 = temp;
- }
-
- if (match_num >= num && match_num <= num2)
- return TRUE;
- }
-
- if (*set != ',')
- return FALSE;
- }
-
- set++;
+ while (set != NULL) {
+ if (seq >= set->seq1 && seq <= set->seq2)
+ return TRUE;
+ set = set->next;
}
return FALSE;
@@ -133,56 +80,56 @@
}
static int search_keyword(struct mail_index *index,
- struct mail_index_record *rec, const char *value)
+ const struct mail_index_record *rec,
+ const char *value)
{
const char **custom_flags;
int i;
- if ((rec->msg_flags & MAIL_CUSTOM_FLAGS_MASK) == 0)
- return FALSE;
+ for (i = 0; i < INDEX_CUSTOM_FLAGS_BYTE_COUNT; i++) {
+ if (rec->custom_flags[i] != 0)
+ break;
+ }
- custom_flags = mail_custom_flags_list_get(index->custom_flags);
+ if (i == INDEX_CUSTOM_FLAGS_BYTE_COUNT)
+ return FALSE; /* no custom flags set */
+
+ /*FIXME:custom_flags = mail_custom_flags_list_get(index->custom_flags);
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
if (custom_flags[i] != NULL &&
strcasecmp(custom_flags[i], value) == 0) {
return rec->msg_flags &
(1 << (MAIL_CUSTOM_FLAG_1_BIT+i));
}
- }
+ }*/
return FALSE;
}
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
static int search_arg_match_index(struct index_mailbox *ibox,
- struct mail_index_record *rec,
- unsigned int client_seq,
+ const struct mail_index_record *rec,
enum mail_search_arg_type type,
const char *value)
{
switch (type) {
case SEARCH_ALL:
return 1;
- case SEARCH_SET:
- return msgset_contains(value, client_seq,
- ibox->synced_messages_count);
- case SEARCH_UID:
- return msgset_contains(value, rec->uid,
- ibox->index->header->next_uid-1);
/* flags */
case SEARCH_ANSWERED:
- return rec->msg_flags & MAIL_ANSWERED;
+ return rec->flags & MAIL_ANSWERED;
case SEARCH_DELETED:
- return rec->msg_flags & MAIL_DELETED;
+ return rec->flags & MAIL_DELETED;
case SEARCH_DRAFT:
- return rec->msg_flags & MAIL_DRAFT;
+ return rec->flags & MAIL_DRAFT;
case SEARCH_FLAGGED:
- return rec->msg_flags & MAIL_FLAGGED;
+ return rec->flags & MAIL_FLAGGED;
case SEARCH_SEEN:
- return rec->msg_flags & MAIL_SEEN;
+ return rec->flags & MAIL_SEEN;
case SEARCH_RECENT:
- return rec->uid >= ibox->index->first_recent_uid;
+ //FIXME:return rec->uid >= ibox->index->first_recent_uid;
+ return FALSE;
case SEARCH_KEYWORD:
return search_keyword(ibox->index, rec, value);
@@ -193,10 +140,22 @@
static void search_index_arg(struct mail_search_arg *arg, void *context)
{
- struct mail_search_context *ctx = context;
+ struct index_search_context *ctx = context;
+ int found;
+
+ if (arg->type == SEARCH_SEQSET) {
+ found = seqset_contains(arg->value.seqset, ctx->mail->seq);
+ ARG_SET_RESULT(arg, found);
+ return;
+ }
+
+ if (ctx->imail.data.rec == NULL) {
+ /* expunged message */
+ ARG_SET_RESULT(arg, 0);
+ return;
+ }
switch (search_arg_match_index(ctx->ibox, ctx->imail.data.rec,
- ctx->mail->seq,
arg->type, arg->value.str)) {
case -1:
/* unknown */
@@ -211,7 +170,7 @@
}
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
-static int search_arg_match_cached(struct mail_search_context *ctx,
+static int search_arg_match_cached(struct index_search_context *ctx,
enum mail_search_arg_type type,
const char *value)
{
@@ -291,7 +250,7 @@
static void search_cached_arg(struct mail_search_arg *arg, void *context)
{
- struct mail_search_context *ctx = context;
+ struct index_search_context *ctx = context;
switch (search_arg_match_cached(ctx, arg->type,
arg->value.str)) {
@@ -340,7 +299,7 @@
}
static struct header_search_context *
-search_header_context(struct mail_search_context *ctx,
+search_header_context(struct index_search_context *ctx,
struct mail_search_arg *arg)
{
int unknown_charset;
@@ -517,7 +476,7 @@
}
static int search_arg_match_text(struct mail_search_arg *args,
- struct mail_search_context *ctx)
+ struct index_search_context *ctx)
{
struct istream *input;
const char *const *headers;
@@ -571,249 +530,180 @@
return TRUE;
}
-static int seq_update(const char *set, unsigned int *first_seq,
- unsigned int *last_seq, unsigned int max_value)
+static int search_msgset_fix(struct index_mailbox *ibox,
+ const struct mail_index_header *hdr,
+ struct mail_search_seqset *set,
+ uint32_t *seq1_r, uint32_t *seq2_r)
{
- unsigned int seq;
- int first = TRUE;
+ for (; set != NULL; set = set->next) {
+ if (set->seq1 == (uint32_t)-1)
+ set->seq1 = hdr->messages_count;
+ if (set->seq2 == (uint32_t)-1)
+ set->seq2 = hdr->messages_count;
- while (*set != '\0') {
- if (*set == '*') {
- seq = max_value;
- set++;
- } else {
- seq = 0;
- while (*set >= '0' && *set <= '9') {
- seq = seq*10 + (*set-'0');
- set++;
- }
+ if (set->seq1 == 0 || set->seq2 == 0 ||
+ set->seq1 > hdr->messages_count ||
+ set->seq2 > hdr->messages_count) {
+ mail_storage_set_syntax_error(ibox->box.storage,
+ "Invalid messageset");
+ return -1;
}
- if (seq == 0)
- return FALSE;
-
- if (*first_seq == 0 || seq < *first_seq)
- *first_seq = seq;
- if (*last_seq == 0 || seq > *last_seq)
- *last_seq = seq;
-
- if (*set != '\0') {
- if (*set == ',')
- first = TRUE;
- else if (*set == ':' && first)
- first = FALSE;
- else
- return FALSE;
- set++;
- }
+ if (*seq1_r > set->seq1 || *seq1_r == 0)
+ *seq1_r = set->seq1;
+ if (*seq2_r < set->seq2)
+ *seq2_r = set->seq2;
}
-
- return TRUE;
+ return 0;
}
-struct search_msgset_context {
- struct index_mailbox *ibox;
-
- unsigned int first_seq, last_seq;
- unsigned int first_uid, last_uid;
-
- struct mail_search_arg *msgset_arg;
- unsigned int msgset_arg_count;
-};
-
-static int search_parse_msgset_args(struct search_msgset_context *ctx,
- struct mail_search_arg *args)
+static int search_parse_msgset_args(struct index_mailbox *ibox,
+ struct mail_search_arg *args,
+ uint32_t *seq1_r, uint32_t *seq2_r)
{
- struct index_mailbox *ibox = ctx->ibox;
+ const struct mail_index_header *hdr;
+ *seq1_r = *seq2_r = 0;
+
+ hdr = mail_index_get_header(ibox->view);
for (; args != NULL; args = args->next) {
- /* FIXME: we don't check if OR condition can limit the range.
- It's a bit tricky and unlikely to affect performance much. */
if (args->type == SEARCH_SUB) {
- if (!search_parse_msgset_args(ctx, args->value.subargs))
- return FALSE;
- } else if (args->type == SEARCH_SET) {
- ctx->msgset_arg = args;
- ctx->msgset_arg_count++;
- if (!seq_update(args->value.str,
- &ctx->first_seq, &ctx->last_seq,
- ibox->synced_messages_count)) {
- mail_storage_set_syntax_error(ibox->box.storage,
- "Invalid messageset: %s",
- args->value.str);
- return FALSE;
- }
- } else if (args->type == SEARCH_UID) {
- ctx->msgset_arg = args;
- ctx->msgset_arg_count++;
- if (!seq_update(args->value.str,
- &ctx->first_uid, &ctx->last_uid,
- ibox->index->header->next_uid-1)) {
- mail_storage_set_syntax_error(ibox->box.storage,
- "Invalid messageset: %s",
- args->value.str);
- return FALSE;
- }
+ if (search_parse_msgset_args(ibox, args->value.subargs,
+ seq1_r, seq2_r) < 0)
+ return -1;
+ } else if (args->type == SEARCH_OR) {
+ /* FIXME: in cases like "SEEN OR 5 7" we shouldn't
+ limit the range, but in cases like "1 OR 5 7" we
+ should expand the range. A bit tricky, we'll
+ just go through everything now to make it work
+ right. */
+ *seq1_r = 1;
+ *seq2_r = hdr->messages_count;
+
+ /* We still have to fix potential seqsets though */
+ if (search_parse_msgset_args(ibox, args->value.subargs,
+ seq1_r, seq2_r) < 0)
+ return -1;
+ } else if (args->type == SEARCH_SEQSET) {
+ if (search_msgset_fix(ibox, hdr, args->value.seqset,
+ seq1_r, seq2_r) < 0)
+ return -1;
} else if (args->type == SEARCH_ALL) {
- /* go through everything */
- ctx->first_seq = 1;
- ctx->last_seq = ibox->synced_messages_count;
- ctx->msgset_arg_count++;
- return TRUE;
+ /* go through everything. don't stop, have to fix
+ seqsets. */
+ *seq1_r = 1;
+ *seq2_r = hdr->messages_count;
}
}
+ return 0;
+}
- return TRUE;
+static int search_limit_lowwater(struct index_mailbox *ibox,
+ uint32_t uid_lowwater, uint32_t *first_seq)
+{
+ const struct mail_index_header *hdr;
+ uint32_t seq1, seq2;
+
+ if (uid_lowwater == 0)
+ return 0;
+
+ hdr = mail_index_get_header(ibox->view);
+ if (mail_index_lookup_uid_range(ibox->view, uid_lowwater,
+ hdr->next_uid-1,
+ &seq1, &seq2) < 0) {
+ mail_storage_set_index_error(ibox);
+ return -1;
+ }
+
+ if (*first_seq < seq1)
+ *first_seq = seq1;
+ return 0;
}
static int search_limit_by_flags(struct index_mailbox *ibox,
struct mail_search_arg *args,
- unsigned int *first_uid,
- unsigned int *last_uid)
+ uint32_t *seq1, uint32_t *seq2)
{
- struct mail_index_header *hdr;
- unsigned int uid;
+ const struct mail_index_header *hdr;
- hdr = ibox->index->header;
+ hdr = mail_index_get_header(ibox->view);
for (; args != NULL; args = args->next) {
if (args->type == SEARCH_SEEN) {
/* SEEN with 0 seen? */
if (!args->not && hdr->seen_messages_count == 0)
- return FALSE;
+ return 0;
if (hdr->seen_messages_count == hdr->messages_count) {
/* UNSEEN with all seen? */
if (args->not)
- return FALSE;
+ return 0;
/* SEEN with all seen */
args->match_always = TRUE;
- } else {
+ } else if (args->not) {
/* UNSEEN with lowwater limiting */
- uid = hdr->first_unseen_uid_lowwater;
- if (args->not && *first_uid < uid)
- *first_uid = uid;
+ if (search_limit_lowwater(ibox,
+ hdr->first_unseen_uid_lowwater,
+ seq1) < 0)
+ return -1;
}
}
if (args->type == SEARCH_DELETED) {
/* DELETED with 0 deleted? */
if (!args->not && hdr->deleted_messages_count == 0)
- return FALSE;
+ return 0;
if (hdr->deleted_messages_count ==
hdr->messages_count) {
/* UNDELETED with all deleted? */
if (args->not)
- return FALSE;
+ return 0;
/* DELETED with all deleted */
args->match_always = TRUE;
- } else {
+ } else if (!args->not) {
/* DELETED with lowwater limiting */
- uid = hdr->first_deleted_uid_lowwater;
- if (!args->not && *first_uid < uid)
- *first_uid = uid;
+ if (search_limit_lowwater(ibox,
+ hdr->first_deleted_uid_lowwater,
+ seq1) < 0)
+ return -1;
}
}
- if (args->type == SEARCH_RECENT) {
+ /*FIXME:if (args->type == SEARCH_RECENT) {
uid = ibox->index->first_recent_uid;
if (!args->not && *first_uid < uid)
*first_uid = ibox->index->first_recent_uid;
else if (args->not && *last_uid >= uid)
*last_uid = uid-1;
- }
- }
-
- return *first_uid <= *last_uid;
-}
-
-static int client_seq_to_uid(struct index_mailbox *ibox,
- unsigned int seq, unsigned int *uid)
-{
- struct mail_index_record *rec;
- unsigned int expunges_before;
-
- if (seq > ibox->synced_messages_count) {
- mail_storage_set_syntax_error(ibox->box.storage,
- "Sequence out of range: %u", seq);
- return FALSE;
+ }*/
}
- if (mail_modifylog_seq_get_expunges(ibox->index->modifylog, seq, seq,
- &expunges_before) == NULL)
- return FALSE;
-
- seq -= expunges_before;
-
- rec = ibox->index->lookup(ibox->index, seq);
- *uid = rec == NULL ? 0 : rec->uid;
- return TRUE;
+ return *seq1 <= *seq2;
}
-static int search_get_msgset(struct index_mailbox *ibox,
- struct mail_search_arg *args,
- struct messageset_context **msgset_r)
+static int search_get_seqset(struct index_search_context *ctx,
+ struct mail_search_arg *args)
{
- struct search_msgset_context ctx;
- unsigned int uid;
-
- memset(&ctx, 0, sizeof(ctx));
- ctx.ibox = ibox;
+ const struct mail_index_header *hdr;
- if (!search_parse_msgset_args(&ctx, args))
+ if (search_parse_msgset_args(ctx->ibox, args,
+ &ctx->seq1, &ctx->seq2) < 0)
return -1;
- /* seq_update() should make sure that these can't happen */
- i_assert(ctx.first_seq <= ctx.last_seq);
- i_assert(ctx.first_uid <= ctx.last_uid);
-
- if (ctx.first_seq > 1) {
- if (!client_seq_to_uid(ibox, ctx.first_seq, &uid))
- return -1;
- if (uid == 0)
- return 0;
-
- if (ctx.first_uid == 0 || uid < ctx.first_uid)
- ctx.first_uid = uid;
- }
-
- if (ctx.last_seq > 1 && ctx.last_seq != ibox->synced_messages_count) {
- if (!client_seq_to_uid(ibox, ctx.last_seq, &uid))
- return -1;
- if (uid == 0)
- return 0;
-
- if (ctx.last_uid == 0 || uid > ctx.last_uid)
- ctx.last_uid = uid;
+ if (ctx->seq1 == 0) {
+ hdr = mail_index_get_header(ctx->ibox->view);
+ ctx->seq1 = 1;
+ ctx->seq2 = hdr->messages_count;
}
- if (ctx.first_uid == 0)
- ctx.first_uid = 1;
- if (ctx.last_uid == 0 || ctx.last_seq == ibox->synced_messages_count)
- ctx.last_uid = ibox->index->header->next_uid-1;
+ i_assert(ctx->seq1 <= ctx->seq2);
/* UNSEEN and DELETED in root search level may limit the range */
- if (!search_limit_by_flags(ibox, args, &ctx.first_uid, &ctx.last_uid))
- return 0;
-
- i_assert(ctx.first_uid <= ctx.last_uid);
-
- if (ctx.msgset_arg != NULL && ctx.msgset_arg_count == 1) {
- /* one messageset argument, we can use it */
- *msgset_r = index_messageset_init(ibox,
- ctx.msgset_arg->value.str,
- ctx.msgset_arg->type == SEARCH_UID, TRUE);
- /* we might be able to limit it some more */
- index_messageset_limit_range(*msgset_r,
- ctx.first_uid, ctx.last_uid);
- ctx.msgset_arg->match_always = TRUE;
- } else {
- *msgset_r = index_messageset_init_range(ibox, ctx.first_uid,
- ctx.last_uid, TRUE);
- }
- return 1;
+ if (search_limit_by_flags(ctx->ibox, args, &ctx->seq1, &ctx->seq2) < 0)
+ return -1;
+ return 0;
}
int index_storage_search_get_sorting(struct mailbox *box __attr_unused__,
@@ -821,80 +711,58 @@
{
/* currently we don't support sorting */
*sort_program = MAIL_SORT_END;
- return TRUE;
+ return 0;
}
struct mail_search_context *
-index_storage_search_init(struct mailbox *box, const char *charset,
- struct mail_search_arg *args,
+index_storage_search_init(struct mailbox_transaction_context *_t,
+ const char *charset, struct mail_search_arg *args,
const enum mail_sort_type *sort_program,
enum mail_fetch_field wanted_fields,
const char *const wanted_headers[])
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_search_context *ctx;
+ struct index_transaction_context *t =
+ (struct index_transaction_context *)_t;
+ struct index_search_context *ctx;
if (sort_program != NULL && *sort_program != MAIL_SORT_END) {
- i_error("BUG: index_storage_search_init(): "
- "invalid sort_program");
- return NULL;
+ i_fatal("BUG: index_storage_search_init(): "
+ "invalid sort_program");
}
- if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_SHARED))
- return NULL;
+ /*FIXME:if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_SHARED))
+ return NULL;*/
- ctx = i_new(struct mail_search_context, 1);
- ctx->ibox = ibox;
+ ctx = i_new(struct index_search_context, 1);
+ ctx->mail_ctx.box = &t->ibox->box;
+ ctx->trans = t;
+ ctx->ibox = t->ibox;
ctx->charset = i_strdup(charset);
ctx->args = args;
- ctx->mail = (struct mail *) &ctx->imail;
- index_mail_init(ibox, &ctx->imail, wanted_fields, wanted_headers);
-
- if (ibox->synced_messages_count == 0)
- return ctx;
+ ctx->mail = &ctx->imail.mail;
+ index_mail_init(t, &ctx->imail, wanted_fields, wanted_headers);
mail_search_args_reset(ctx->args, TRUE);
- /* see if we can limit the records we look at */
- switch (search_get_msgset(ibox, args, &ctx->msgset_ctx)) {
- case -1:
- /* error */
+ if (search_get_seqset(ctx, args) < 0) {
ctx->failed = TRUE;
- return ctx;
- case 0:
- /* nothing found */
- return ctx;
+ ctx->seq1 = 1;
+ ctx->seq2 = 0;
}
-
- return ctx;
+ return &ctx->mail_ctx;
}
-int index_storage_search_deinit(struct mail_search_context *ctx, int *all_found)
+int index_storage_search_deinit(struct mail_search_context *_ctx)
{
- int ret, msgset_ret;
-
- ret = !ctx->failed && ctx->error == NULL;
+ struct index_search_context *ctx = (struct index_search_context *)_ctx;
+ int ret;
- if (ctx->msgset_ctx != NULL) {
- msgset_ret = index_messageset_deinit(ctx->msgset_ctx);
- if (msgset_ret < 0)
- ret = FALSE;
- if (all_found != NULL)
- *all_found = msgset_ret > 0;
- } else {
- if (all_found != NULL)
- *all_found = !ctx->failed;
- }
+ ret = ctx->failed || ctx->error != NULL ? -1 : 0;
- if (ctx->ibox->fetch_mail.pool != NULL)
- index_mail_deinit(&ctx->ibox->fetch_mail);
if (ctx->imail.pool != NULL)
index_mail_deinit(&ctx->imail);
- if (!index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK))
- ret = FALSE;
-
if (ctx->error != NULL) {
mail_storage_set_error(ctx->ibox->box.storage,
"%s", ctx->error);
@@ -907,7 +775,7 @@
return ret;
}
-static int search_match_next(struct mail_search_context *ctx)
+static int search_match_next(struct index_search_context *ctx)
{
struct mail_search_arg *arg;
int ret;
@@ -918,6 +786,12 @@
if (ret >= 0)
return ret > 0;
+ if (ctx->imail.data.rec == NULL) {
+ /* expunged message, no way to check if the rest would have
+ matched */
+ return FALSE;
+ }
+
/* next search only from cached arguments */
ret = mail_search_args_foreach(ctx->args, search_cached_arg, ctx);
if (ret >= 0)
@@ -935,33 +809,27 @@
return TRUE;
}
-struct mail *index_storage_search_next(struct mail_search_context *ctx)
+struct mail *index_storage_search_next(struct mail_search_context *_ctx)
{
- const struct messageset_mail *msgset_mail;
+ struct index_search_context *ctx = (struct index_search_context *)_ctx;
+ const struct mail_index_record *rec;
int ret;
- if (ctx->msgset_ctx == NULL) {
- /* initialization failed or didn't found any messages */
- return NULL;
- }
-
- do {
- msgset_mail = index_messageset_next(ctx->msgset_ctx);
- if (msgset_mail == NULL) {
- ret = -1;
- break;
+ ret = 0;
+ while (ctx->seq1 <= ctx->seq2) {
+ if (mail_index_lookup(ctx->ibox->view, ctx->seq1, &rec) < 0) {
+ ctx->failed = TRUE;
+ mail_storage_set_index_error(ctx->ibox);
+ return NULL;
}
- ctx->mail->seq = msgset_mail->client_seq;
- ctx->mail->uid = msgset_mail->rec->uid;
+ ctx->imail.data.rec = rec;
+ ctx->mail->seq = ctx->seq1++;
+ ctx->mail->uid = rec == NULL ? 0 : rec->uid;
- ret = index_mail_next(&ctx->imail, msgset_mail->rec,
- msgset_mail->idx_seq, TRUE);
- if (ret <= 0) {
- if (ret < 0)
- break;
- continue;
- }
+ ret = index_mail_next(&ctx->imail, rec, ctx->mail->seq, TRUE);
+ if (ret < 0)
+ break;
t_push();
ret = search_match_next(ctx);
@@ -969,11 +837,12 @@
if (ctx->error != NULL)
ret = -1;
- } while (ret == 0);
+ if (ret != 0)
+ break;
+ }
- if (ret < 0) {
+ if (ret <= 0) {
/* error or last record */
- index_mail_deinit(&ctx->imail);
return NULL;
}
Index: index-status.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-status.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- index-status.c 15 Jun 2003 03:42:29 -0000 1.26
+++ index-status.c 27 Apr 2004 20:25:54 -0000 1.27
@@ -1,69 +1,13 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
-#include "mail-custom-flags.h"
-#include "mail-index-util.h"
#include "index-storage.h"
#define STATUS_MESSAGE_COUNTS \
(STATUS_MESSAGES | STATUS_RECENT | STATUS_UIDNEXT | \
STATUS_UIDVALIDITY | STATUS_UNSEEN | STATUS_FIRST_UNSEEN_SEQ)
-static unsigned int get_first_unseen_seq(struct mail_index *index)
-{
- struct mail_index_header *hdr;
- struct mail_index_record *rec;
- unsigned int seq, lowwater_uid;
-
- hdr = mail_index_get_header(index);
- if (hdr->seen_messages_count == hdr->messages_count) {
- /* no unseen messages */
- return 0;
- }
-
- lowwater_uid = hdr->first_unseen_uid_lowwater;
- if (lowwater_uid == hdr->next_uid) {
- /* no unseen messages */
- rec = NULL;
- } else if (lowwater_uid > hdr->next_uid) {
- index_set_corrupted(index, "first_unseen_uid_lowwater %u >= "
- "next_uid %u", lowwater_uid, hdr->next_uid);
- return 0;
- } else if (lowwater_uid != 0) {
- /* begin scanning from the low water mark */
- rec = index->lookup_uid_range(index, lowwater_uid,
- hdr->next_uid - 1, &seq);
- } else {
- /* begin scanning from the beginning */
- rec = index->lookup(index, 1);
- seq = 1;
- }
-
- while (rec != NULL && (rec->msg_flags & MAIL_SEEN)) {
- rec = index->next(index, rec);
- seq++;
- }
-
- if (rec == NULL) {
- index_set_corrupted(index, "No unseen messages found with "
- "first_unseen_uid_lowwater %u, "
- "seen_messages_count %u, messages_count %u",
- lowwater_uid, hdr->seen_messages_count,
- hdr->messages_count);
- return 0;
- }
-
- if (rec->uid != lowwater_uid) {
- /* update the low water mark if we can get exclusive
- lock immediately. */
- if (index->try_lock(index, MAIL_LOCK_EXCLUSIVE))
- hdr->first_unseen_uid_lowwater = rec->uid;
- }
-
- return seq;
-}
-
-static void
+/*static void
get_custom_flags(struct mail_custom_flags *mcf, struct mailbox_status *status)
{
const char **flags;
@@ -75,55 +19,47 @@
flags = mail_custom_flags_list_get(mcf);
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++)
status->custom_flags[i] = t_strdup(flags[i]);
-}
+}*/
int index_storage_get_status(struct mailbox *box,
enum mailbox_status_items items,
struct mailbox_status *status)
{
struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_index_header *hdr;
+ const struct mail_index_header *hdr;
memset(status, 0, sizeof(struct mailbox_status));
if ((items & STATUS_MESSAGE_COUNTS) != 0) {
- /* if we're doing STATUS for selected mailbox, we have to sync
- it first or STATUS reply may give different data */
- if (!index_storage_sync_and_lock(ibox, TRUE, FALSE,
- MAIL_LOCK_UNLOCK))
- return FALSE;
-
- if (!index_storage_sync_modifylog(ibox, FALSE)) {
- (void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
- return FALSE;
- }
- } else {
- if (!index_storage_lock(ibox, MAIL_LOCK_SHARED))
- return FALSE;
+ /* sync mailbox to update message counts */
+ if (mailbox_sync(box, 0) < 0)
+ return -1;
}
/* we can get most of the status items without any trouble */
- hdr = mail_index_get_header(ibox->index);
+ hdr = mail_index_get_header(ibox->view);
if ((items & STATUS_MESSAGE_COUNTS) != 0) {
status->messages = hdr->messages_count;
status->unseen = hdr->messages_count - hdr->seen_messages_count;
status->uidvalidity = hdr->uid_validity;
status->uidnext = hdr->next_uid;
}
- status->diskspace_full = ibox->index->nodiskspace;
+ //FIXME:status->diskspace_full = ibox->nodiskspace;
if (items & STATUS_FIRST_UNSEEN_SEQ) {
- status->first_unseen_seq =
- get_first_unseen_seq(ibox->index);
+ if (mail_index_lookup_first(ibox->view, 0, MAIL_SEEN,
+ &status->first_unseen_seq) < 0) {
+ mail_storage_set_index_error(ibox);
+ return -1;
+ }
}
- if (items & STATUS_RECENT)
- status->recent = index_storage_get_recent_count(ibox->index);
+ /*FIXME:if (items & STATUS_RECENT)
+ status->recent = index_storage_get_recent_count(view);*/
- if (items & STATUS_CUSTOM_FLAGS)
- get_custom_flags(ibox->index->custom_flags, status);
+ /*FIXME:if (items & STATUS_CUSTOM_FLAGS)
+ get_custom_flags(ibox, status);*/
- if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
- return FALSE;
- return TRUE;
+ mail_index_view_unlock(ibox->view);
+ return 0;
}
Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- index-storage.c 20 Oct 2003 04:15:18 -0000 1.41
+++ index-storage.c 27 Apr 2004 20:25:54 -0000 1.42
@@ -1,10 +1,8 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "mail-index.h"
-#include "mail-index-util.h"
-#include "mail-custom-flags.h"
#include "index-storage.h"
#include <stdlib.h>
@@ -23,8 +21,12 @@
struct index_list *next;
struct mail_index *index;
+ char *mailbox_path;
int refcount;
+ dev_t index_dir_dev;
+ ino_t index_dir_ino;
+
time_t destroy_time;
};
@@ -32,12 +34,12 @@
static struct timeout *to_index = NULL;
static int index_storage_refcount = 0;
-void index_storage_init(struct mail_storage *storage __attr_unused__)
+void index_storage_init(struct index_storage *storage __attr_unused__)
{
index_storage_refcount++;
}
-void index_storage_deinit(struct mail_storage *storage __attr_unused__)
+void index_storage_deinit(struct index_storage *storage __attr_unused__)
{
if (--index_storage_refcount > 0)
return;
@@ -45,7 +47,8 @@
index_storage_destroy_unrefed();
}
-void index_storage_add(struct mail_index *index)
+static void index_storage_add(struct mail_index *index,
+ const char *mailbox_path, struct stat *st)
{
struct index_list *list;
@@ -53,43 +56,56 @@
list->refcount = 1;
list->index = index;
+ list->mailbox_path = i_strdup(mailbox_path);
+ list->index_dir_dev = st->st_dev;
+ list->index_dir_ino = st->st_ino;
+
list->next = indexes;
indexes = list;
}
+static void index_list_free(struct index_list *list)
+{
+ mail_index_free(list->index);
+ i_free(list->mailbox_path);
+ i_free(list);
+}
+
struct mail_index *
-index_storage_lookup_ref(const char *index_dir, const char *path)
+index_storage_alloc(const char *index_dir, const char *mailbox_path,
+ const char *prefix)
{
struct index_list **list, *rec;
- struct mail_index *match;
- struct stat st1, st2;
+ struct mail_index *index;
+ struct stat st;
int destroy_count;
if (index_dir != NULL) {
- if (stat(index_dir, &st1) < 0)
+ if (stat(index_dir, &st) < 0)
return NULL;
+ } else {
+ memset(&st, 0, sizeof(st));
}
/* compare index_dir inodes so we don't break even with symlinks.
for in-memory indexes compare just mailbox paths */
- destroy_count = 0; match = NULL;
+ destroy_count = 0; index = NULL;
for (list = &indexes; *list != NULL;) {
rec = *list;
- if ((index_dir != NULL && stat(rec->index->dir, &st2) == 0 &&
- st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev) ||
- (index_dir == NULL &&
- strcmp(path, rec->index->mailbox_path) == 0)) {
+ if ((index_dir != NULL && st.st_ino == rec->index_dir_ino &&
+ st.st_dev == rec->index_dir_dev) ||
+ (index_dir == NULL && st.st_ino == 0 &&
+ strcmp(mailbox_path, rec->mailbox_path) == 0)) {
rec->refcount++;
- match = rec->index;
+ index = rec->index;
}
if (rec->refcount == 0) {
if (rec->destroy_time <= ioloop_time ||
destroy_count >= INDEX_CACHE_MAX) {
- rec->index->free(rec->index);
*list = rec->next;
- i_free(rec);
+ index_list_free(rec);
continue;
} else {
destroy_count++;
@@ -99,7 +115,12 @@
list = &(*list)->next;
}
- return match;
+ if (index == NULL) {
+ index = mail_index_alloc(index_dir, prefix);
+ index_storage_add(index, mailbox_path, &st);
+ }
+
+ return index;
}
static void destroy_unrefed(int all)
@@ -111,9 +132,8 @@
if (rec->refcount == 0 &&
(all || rec->destroy_time <= ioloop_time)) {
- rec->index->free(rec->index);
*list = rec->next;
- i_free(rec);
+ index_list_free(rec);
} else {
list = &(*list)->next;
}
@@ -223,11 +243,11 @@
return ret;
}
-static void lock_notify(enum mail_lock_notify_type notify_type,
+static void lock_notify(enum mailbox_lock_notify_type notify_type,
unsigned int secs_left, void *context)
{
struct index_mailbox *ibox = context;
- struct mail_storage *storage = ibox->box.storage;
+ struct index_storage *storage = ibox->storage;
const char *str;
time_t now;
@@ -241,10 +261,10 @@
/* if notify type changes, print the message immediately */
now = time(NULL);
- if (ibox->last_notify_type == (enum mail_lock_notify_type)-1 ||
+ if (ibox->last_notify_type == MAILBOX_LOCK_NOTIFY_NONE ||
ibox->last_notify_type == notify_type) {
- if (ibox->last_notify_type == (enum mail_lock_notify_type)-1 &&
- notify_type == MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE) {
+ if (ibox->last_notify_type == MAILBOX_LOCK_NOTIFY_NONE &&
+ notify_type == MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE) {
/* first override notification, show it */
} else {
if (now < ibox->next_lock_notify || secs_left < 15)
@@ -256,73 +276,31 @@
ibox->last_notify_type = notify_type;
switch (notify_type) {
- case MAIL_LOCK_NOTIFY_MAILBOX_ABORT:
+ case MAILBOX_LOCK_NOTIFY_NONE:
+ break;
+ case MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT:
str = t_strdup_printf("Mailbox is locked, will abort in "
"%u seconds", secs_left);
storage->callbacks->notify_no(&ibox->box, str,
storage->callback_context);
break;
- case MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE:
+ case MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE:
str = t_strdup_printf("Stale mailbox lock file detected, "
"will override in %u seconds", secs_left);
storage->callbacks->notify_ok(&ibox->box, str,
storage->callback_context);
break;
- case MAIL_LOCK_NOTIFY_INDEX_ABORT:
- str = t_strdup_printf("Mailbox index is locked, will abort in "
- "%u seconds", secs_left);
- storage->callbacks->notify_no(&ibox->box, str,
- storage->callback_context);
- break;
}
}
-void index_storage_init_lock_notify(struct index_mailbox *ibox)
+void index_storage_reset_lock_notify(struct index_mailbox *ibox)
{
- if (ibox->index->mailbox_readonly)
- ibox->readonly = TRUE;
-
ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL;
- ibox->last_notify_type = (enum mail_lock_notify_type)-1;
-
- ibox->index->set_lock_notify_callback(ibox->index, lock_notify, ibox);
-}
-
-int index_storage_lock(struct index_mailbox *ibox,
- enum mail_lock_type lock_type)
-{
- int ret = TRUE;
-
- if (lock_type == MAIL_LOCK_UNLOCK) {
- if (ibox->trans_ctx != NULL) {
- if (!mail_cache_transaction_commit(ibox->trans_ctx))
- ret = FALSE;
- if (!mail_cache_transaction_end(ibox->trans_ctx))
- ret = FALSE;
- ibox->trans_ctx = NULL;
- }
- if (ibox->lock_type != MAILBOX_LOCK_UNLOCK)
- return TRUE;
- } else {
- if (ibox->lock_type == MAIL_LOCK_EXCLUSIVE)
- return TRUE;
- }
-
- /* we have to set/reset this every time, because the same index
- may be used by multiple IndexMailboxes. */
- index_storage_init_lock_notify(ibox);
- if (!ibox->index->set_lock(ibox->index, lock_type))
- ret = FALSE;
- ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
-
- if (!ret)
- return mail_storage_set_index_error(ibox);
-
- return TRUE;
+ ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE;
}
struct index_mailbox *
-index_storage_mailbox_init(struct mail_storage *storage, struct mailbox *box,
+index_storage_mailbox_init(struct index_storage *storage, struct mailbox *box,
struct mail_index *index, const char *name,
enum mailbox_open_flags flags)
{
@@ -334,52 +312,38 @@
index_flags = MAIL_INDEX_OPEN_FLAG_CREATE;
if ((flags & MAILBOX_OPEN_FAST) != 0)
index_flags |= MAIL_INDEX_OPEN_FLAG_FAST;
- if ((flags & MAILBOX_OPEN_READONLY) != 0)
- index_flags |= MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT;
- if ((flags & MAILBOX_OPEN_MMAP_INVALIDATE) != 0)
- index_flags |= MAIL_INDEX_OPEN_FLAG_MMAP_INVALIDATE;
do {
ibox = i_new(struct index_mailbox, 1);
ibox->box = *box;
+ ibox->storage = storage;
- ibox->box.storage = storage;
+ ibox->box.storage = &storage->storage;
ibox->box.name = i_strdup(name);
ibox->readonly = (flags & MAILBOX_OPEN_READONLY) != 0;
ibox->index = index;
ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL;
- index->set_lock_notify_callback(index, lock_notify, ibox);
-
- if (!index->opened) {
- /* open the index first */
- if (!index->open(index, index_flags))
- break;
-
- mail_cache_set_defaults(index->cache,
- get_default_cache_fields(),
- get_never_cache_fields());
-
- if (INDEX_IS_IN_MEMORY(index) &&
- storage->index_dir != NULL) {
- storage->callbacks->notify_no(&ibox->box,
- "Couldn't use index files",
- storage->callback_context);
- }
- }
+ ibox->commit_log_file_seq = 0;
+ ibox->mail_read_mmaped = getenv("MAIL_READ_MMAPED") != NULL;
- if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_SHARED))
+ if (mail_index_open(index, index_flags) < 0)
break;
- ibox->synced_messages_count =
- mail_index_get_header(index)->messages_count;
-
- if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
- break;
+ ibox->cache = mail_index_get_cache(index);
+ mail_cache_set_defaults(ibox->cache,
+ get_default_cache_fields(),
+ get_never_cache_fields());
- index->set_lock_notify_callback(index, NULL, NULL);
+ if (mail_index_is_in_memory(index) &&
+ storage->index_dir != NULL) {
+ storage->callbacks->notify_no(&ibox->box,
+ "Couldn't use index files",
+ storage->callback_context);
+ }
+ ibox->view = mail_index_view_open(index);
return ibox;
} while (0);
@@ -388,21 +352,21 @@
return NULL;
}
-int index_storage_mailbox_free(struct mailbox *box)
+void index_storage_mailbox_free(struct mailbox *box)
{
struct index_mailbox *ibox = (struct index_mailbox *) box;
/* make sure we're unlocked */
- (void)ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK);
+ mail_index_view_unlock(ibox->view);
index_mailbox_check_remove_all(ibox);
if (ibox->index != NULL)
index_storage_unref(ibox->index);
+ i_free(ibox->path);
+ i_free(ibox->control_dir);
i_free(box->name);
i_free(box);
-
- return TRUE;
}
int index_storage_is_readonly(struct mailbox *box)
@@ -416,51 +380,41 @@
{
struct index_mailbox *ibox = (struct index_mailbox *) box;
- return ibox->index->allow_new_custom_flags;
+ /* FIXME: return FALSE if we're full */
+ return !ibox->readonly;
}
-int index_storage_is_inconsistency_error(struct mailbox *box)
+int index_storage_is_inconsistent(struct mailbox *box)
{
struct index_mailbox *ibox = (struct index_mailbox *) box;
- return ibox->inconsistent;
+ return mail_index_view_is_inconsistent(ibox->view);
}
-void index_storage_set_callbacks(struct mail_storage *storage,
+void index_storage_set_callbacks(struct mail_storage *_storage,
struct mail_storage_callbacks *callbacks,
void *context)
{
- memcpy(storage->callbacks, callbacks,
- sizeof(struct mail_storage_callbacks));
+ struct index_storage *storage = (struct index_storage *) _storage;
+
+ *storage->callbacks = *callbacks;
storage->callback_context = context;
}
int mail_storage_set_index_error(struct index_mailbox *ibox)
{
- switch (ibox->index->get_last_error(ibox->index)) {
+ switch (mail_index_get_last_error(ibox->index)) {
case MAIL_INDEX_ERROR_NONE:
case MAIL_INDEX_ERROR_INTERNAL:
mail_storage_set_internal_error(ibox->box.storage);
break;
- case MAIL_INDEX_ERROR_INCONSISTENT:
- ibox->inconsistent = TRUE;
- break;
case MAIL_INDEX_ERROR_DISKSPACE:
mail_storage_set_error(ibox->box.storage, "Out of disk space");
break;
- case MAIL_INDEX_ERROR_INDEX_LOCK_TIMEOUT:
- mail_storage_set_error(ibox->box.storage,
- "Timeout while waiting for lock to index of mailbox %s",
- ibox->box.name);
- break;
- case MAIL_INDEX_ERROR_MAILBOX_LOCK_TIMEOUT:
- mail_storage_set_error(ibox->box.storage,
- "Timeout while waiting for lock to mailbox %s",
- ibox->box.name);
- break;
}
- index_reset_error(ibox->index);
+ mail_index_view_unlock(ibox->view);
+ mail_index_reset_error(ibox->index);
return FALSE;
}
@@ -469,9 +423,9 @@
const char *custom_flags[],
unsigned int custom_flags_count)
{
- int ret;
+ /*FIXME:int ret;
- ret = mail_custom_flags_fix_list(ibox->index->custom_flags,
+ ret = mail_custom_flags_fix_list(ibox->index,
flags, custom_flags,
custom_flags_count);
switch (ret) {
@@ -483,16 +437,17 @@
return FALSE;
default:
return mail_storage_set_index_error(ibox);
- }
+ }*/
}
-unsigned int index_storage_get_recent_count(struct mail_index *index)
+unsigned int index_storage_get_recent_count(struct mail_index_view *view)
{
+#if 0
struct mail_index_header *hdr;
struct mail_index_record *rec;
unsigned int seq;
- hdr = mail_index_get_header(index);
+ hdr = mail_index_get_header(view);
if (index->first_recent_uid <= 1) {
/* all are recent */
return hdr->messages_count;
@@ -502,7 +457,9 @@
if (index->first_recent_uid >= hdr->next_uid)
return 0;
- rec = index->lookup_uid_range(index, index->first_recent_uid,
- hdr->next_uid - 1, &seq);
+ rec = mail_index_lookup_uid_range(view, index->first_recent_uid,
+ hdr->next_uid - 1, &seq);
return rec == NULL ? 0 : hdr->messages_count+1 - seq;
+#endif
+ return 0;
}
Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- index-storage.h 26 Oct 2003 20:13:15 -0000 1.53
+++ index-storage.h 27 Apr 2004 20:25:54 -0000 1.54
@@ -1,10 +1,26 @@
#ifndef __INDEX_STORAGE_H
#define __INDEX_STORAGE_H
-#include "mail-storage.h"
+#include "mail-storage-private.h"
#include "mail-index.h"
#include "index-mail.h"
+/* Max. mmap()ed size for a message */
+#define MAIL_MMAP_BLOCK_SIZE (1024*256)
+/* Block size when read()ing message. */
+#define MAIL_READ_BLOCK_SIZE (1024*8)
+
+#define MAILBOX_FULL_SYNC_INTERVAL 5
+
+enum mailbox_lock_notify_type {
+ MAILBOX_LOCK_NOTIFY_NONE,
+
+ /* Mailbox is locked, will abort in secs_left */
+ MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
+ /* Mailbox lock looks stale, will override in secs_left */
+ MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE
+};
+
struct index_autosync_file {
struct index_autosync_file *next;
@@ -18,16 +34,30 @@
int fd;
};
+struct index_storage {
+ struct mail_storage storage;
+
+ char *dir; /* root directory */
+ char *index_dir;
+ char *control_dir;
+ char *inbox_path; /* INBOX location */
+
+ char *user; /* name of user accessing the storage */
+
+ struct mail_storage_callbacks *callbacks;
+ void *callback_context;
+};
+
struct index_mailbox {
struct mailbox box;
-
- /* expunge messages marked as deleted, requires index to be
- exclusively locked */
- void (*mail_init)(struct index_mail *mail);
+ struct index_storage *storage;
+ char *path, *control_dir;
struct mail_index *index;
- enum mailbox_lock_type lock_type;
- struct mail_cache_transaction_ctx *trans_ctx;
+ struct mail_index_view *view;
+ struct mail_cache *cache;
+ struct mail_cache_view *cache_view;
+ struct mail *mail_interface;
struct timeout *autosync_to;
struct index_autosync_file *autosync_files;
@@ -36,59 +66,72 @@
time_t sync_last_check, sync_last_notify;
unsigned int min_newmail_notify_interval;
- struct index_mail fetch_mail; /* fetch_uid() or fetch_seq() */
- unsigned int synced_messages_count;
-
time_t next_lock_notify; /* temporary */
- enum mail_lock_notify_type last_notify_type;
+ enum mailbox_lock_notify_type last_notify_type;
+
+ uint32_t commit_log_file_seq;
+ uoff_t commit_log_file_offset;
+
+ /* sync: */
+ struct maildir_uidlist *uidlist;
+ time_t last_new_mtime, last_cur_mtime, last_sync;
+
+ mode_t mail_create_mode;
+ unsigned int private_flags_mask;
unsigned int readonly:1;
- unsigned int inconsistent:1;
unsigned int sent_diskspace_warning:1;
unsigned int sent_readonly_flags_warning:1;
unsigned int autosync_pending:1;
+ unsigned int mail_read_mmaped:1;
+
+ unsigned int maildir_keep_new:1;
+};
+
+struct index_transaction_context {
+ struct mailbox_transaction_context mailbox_ctx;
+ struct index_mailbox *ibox;
+ struct mail_index_transaction *trans;
+ struct mail_cache_transaction_ctx *cache_trans;
+
+ struct index_mail fetch_mail; /* for index_storage_fetch() */
};
int mail_storage_set_index_error(struct index_mailbox *ibox);
-void index_storage_init_lock_notify(struct index_mailbox *ibox);
-int index_storage_lock(struct index_mailbox *ibox,
- enum mail_lock_type lock_type);
+void index_storage_reset_lock_notify(struct index_mailbox *ibox);
-void index_storage_add(struct mail_index *index);
struct mail_index *
-index_storage_lookup_ref(const char *index_dir, const char *path);
+index_storage_alloc(const char *index_dir,
+ const char *mailbox_path, const char *prefix);
void index_storage_unref(struct mail_index *index);
void index_storage_destroy_unrefed(void);
-void index_storage_init(struct mail_storage *storage);
-void index_storage_deinit(struct mail_storage *storage);
+void index_storage_init(struct index_storage *storage);
+void index_storage_deinit(struct index_storage *storage);
struct index_mailbox *
-index_storage_mailbox_init(struct mail_storage *storage, struct mailbox *box,
+index_storage_mailbox_init(struct index_storage *storage, struct mailbox *box,
struct mail_index *index, const char *name,
enum mailbox_open_flags flags);
-int index_storage_mailbox_free(struct mailbox *box);
+void index_storage_mailbox_free(struct mailbox *box);
int index_storage_is_readonly(struct mailbox *box);
int index_storage_allow_new_custom_flags(struct mailbox *box);
-int index_storage_is_inconsistency_error(struct mailbox *box);
-
-int index_storage_sync_and_lock(struct index_mailbox *ibox,
- int sync_size, int minimal_sync,
- enum mail_lock_type data_lock_type);
-int index_storage_sync_modifylog(struct index_mailbox *ibox, int hide_deleted);
+int index_storage_is_inconsistent(struct mailbox *box);
int index_mailbox_fix_custom_flags(struct index_mailbox *ibox,
enum mail_flags *flags,
const char *custom_flags[],
unsigned int custom_flags_count);
-unsigned int index_storage_get_recent_count(struct mail_index *index);
+unsigned int index_storage_get_recent_count(struct mail_index_view *view);
void index_mailbox_check_add(struct index_mailbox *ibox,
const char *path, int dir);
void index_mailbox_check_remove_all(struct index_mailbox *ibox);
+int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags);
+
/* mailbox methods: */
void index_storage_set_callbacks(struct mail_storage *storage,
struct mail_storage_callbacks *callbacks,
@@ -96,31 +139,27 @@
int index_storage_get_status(struct mailbox *box,
enum mailbox_status_items items,
struct mailbox_status *status);
-int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags);
-struct mail *index_storage_fetch_uid(struct mailbox *box, unsigned int uid,
- enum mail_fetch_field wanted_fields);
-struct mail *index_storage_fetch_seq(struct mailbox *box, unsigned int seq,
- enum mail_fetch_field wanted_fields);
+struct mail *
+index_storage_fetch(struct mailbox_transaction_context *t, uint32_t seq,
+ enum mail_fetch_field wanted_fields);
+int index_storage_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2,
+ uint32_t *seq1_r, uint32_t *seq2_r);
int index_storage_search_get_sorting(struct mailbox *box,
enum mail_sort_type *sort_program);
struct mail_search_context *
-index_storage_search_init(struct mailbox *box, const char *charset,
- struct mail_search_arg *args,
+index_storage_search_init(struct mailbox_transaction_context *t,
+ const char *charset, struct mail_search_arg *args,
const enum mail_sort_type *sort_program,
enum mail_fetch_field wanted_fields,
const char *const wanted_headers[]);
-int index_storage_search_deinit(struct mail_search_context *ctx,
- int *all_found);
+int index_storage_search_deinit(struct mail_search_context *ctx);
struct mail *index_storage_search_next(struct mail_search_context *ctx);
-struct mail_copy_context *index_storage_copy_init(struct mailbox *box);
-int index_storage_copy_deinit(struct mail_copy_context *ctx, int rollback);
-int index_storage_copy(struct mail *mail, struct mail_copy_context *ctx);
-
-int index_storage_update_flags(struct mail *mail,
- const struct mail_full_flags *flags,
- enum modify_type modify_type);
+struct mailbox_transaction_context *
+index_transaction_begin(struct mailbox *box);
+int index_transaction_commit(struct mailbox_transaction_context *t);
+void index_transaction_rollback(struct mailbox_transaction_context *t);
#endif
Index: index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-sync.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- index-sync.c 24 Aug 2003 12:45:33 -0000 1.27
+++ index-sync.c 27 Apr 2004 20:25:54 -0000 1.28
@@ -1,250 +1,89 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
-#include "ioloop.h"
#include "index-storage.h"
-#include "mail-index-util.h"
-#include "mail-modifylog.h"
-#include "mail-custom-flags.h"
-/* How often to do full sync when fast sync flag is set. */
-#define MAILBOX_FULL_SYNC_INTERVAL 5
-
-static void index_storage_sync_size(struct index_mailbox *ibox)
+int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
{
- struct mail_storage *storage = ibox->box.storage;
- unsigned int messages, recent;
-
- if (storage->callbacks->new_messages == NULL)
- return;
-
- messages = ibox->index->get_header(ibox->index)->messages_count;
- messages += mail_modifylog_get_expunge_count(ibox->index->modifylog);
+ struct index_mailbox *ibox = (struct index_mailbox *)box;
+ struct mail_index_view_sync_ctx *ctx;
+ struct mail_full_flags full_flags;
+ const struct mail_index_record *rec;
+ struct mail_index_sync_rec sync;
+ struct mail_storage_callbacks *sc;
+ const uint32_t *expunges;
+ size_t i, expunges_count;
+ void *sc_context;
+ enum mail_index_sync_type sync_mask;
+ uint32_t seq, new_count;
+ int ret, appends;
- if (messages != ibox->synced_messages_count) {
- i_assert(messages > ibox->synced_messages_count);
+ sync_mask = MAIL_INDEX_SYNC_MASK_ALL;
+ if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
+ sync_mask &= ~MAIL_INDEX_SYNC_TYPE_EXPUNGE;
- /* new messages in mailbox */
- recent = index_storage_get_recent_count(ibox->index);
- storage->callbacks->new_messages(&ibox->box, messages, recent,
- storage->callback_context);
- ibox->synced_messages_count = messages;
+ if (mail_index_view_sync_begin(ibox->view, sync_mask, &ctx) < 0) {
+ mail_storage_set_index_error(ibox);
+ return -1;
}
-}
-
-int index_storage_sync_and_lock(struct index_mailbox *ibox,
- int sync_size, int minimal_sync,
- enum mail_lock_type data_lock_type)
-{
- struct mail_storage *storage = ibox->box.storage;
- struct mail_index *index = ibox->index;
- int failed, changes, set_shared_lock;
-
- set_shared_lock = ibox->index->lock_type != MAIL_LOCK_EXCLUSIVE;
- index_storage_init_lock_notify(ibox);
- failed = !index->sync_and_lock(index, minimal_sync,
- data_lock_type, &changes);
- ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
-
- if (!failed) {
- /* reset every time it has worked */
- ibox->sent_diskspace_warning = FALSE;
+ if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) {
+ expunges_count = 0;
+ expunges = NULL;
} else {
- if (index->get_last_error(index) !=
- MAIL_INDEX_ERROR_DISKSPACE) {
- (void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
- return mail_storage_set_index_error(ibox);
- }
-
- /* notify client once about it */
- if (!ibox->sent_diskspace_warning &&
- storage->callbacks->alert_no_diskspace != NULL) {
- ibox->sent_diskspace_warning = TRUE;
- storage->callbacks->alert_no_diskspace(
- &ibox->box, storage->callback_context);
- }
-
- index_reset_error(index);
- }
-
- if (set_shared_lock) {
- /* just make sure we are locked, and that we drop our
- exclusive lock if it wasn't wanted originally */
- if (!index_storage_lock(ibox, MAIL_LOCK_SHARED)) {
- (void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
- return FALSE;
- }
- }
-
- /* notify about changes in mailbox size. */
- if (!changes)
- return TRUE; /* no changes - must be no new mail either */
-
- if (sync_size)
- index_storage_sync_size(ibox);
-
- /* notify changes in custom flags */
- if (mail_custom_flags_has_changes(index->custom_flags) &&
- storage->callbacks->new_custom_flags != NULL) {
- storage->callbacks->new_custom_flags(&ibox->box,
- mail_custom_flags_list_get(index->custom_flags),
- MAIL_CUSTOM_FLAGS_COUNT, storage->callback_context);
+ expunges =
+ mail_index_view_sync_get_expunges(ctx, &expunges_count);
}
- return TRUE;
-}
-
-int index_storage_sync_modifylog(struct index_mailbox *ibox, int hide_deleted)
-{
- const struct modify_log_record *log1, *log2, *log, *first_flag_log;
- struct mail_index_record *rec;
- struct mail_full_flags flags;
- struct mail_storage_callbacks *sc;
- void *sc_context;
- unsigned int count1, count2, total_count, seq, seq_count, i, messages;
- unsigned int first_flag_change, first_flag_messages_count;
-
- /* show the log */
- if (!mail_modifylog_get_nonsynced(ibox->index->modifylog,
- &log1, &count1, &log2, &count2))
- return mail_storage_set_index_error(ibox);
-
- sc = ibox->box.storage->callbacks;
- sc_context = ibox->box.storage->callback_context;
-
- /* first show expunges. this makes it easier to deal with sequence
- numbers. */
- total_count = count1 + count2;
- messages = ibox->synced_messages_count;
- first_flag_change = total_count;
- first_flag_log = NULL;
- first_flag_messages_count = 0;
-
- for (i = 0, log = log1; i < total_count; i++, log++) {
- if (i == count1)
- log = log2;
-
- if (log->seq1 > messages) {
- /* client doesn't know about this message yet */
- continue;
- }
-
- switch (log->type) {
- case RECORD_TYPE_EXPUNGE:
- seq_count = (log->seq2 - log->seq1) + 1;
- messages -= seq_count;
-
- if (sc->expunge == NULL)
- break;
+ sc = ibox->storage->callbacks;
+ sc_context = ibox->storage->callback_context;
+ appends = FALSE;
- for (; seq_count > 0; seq_count--) {
- sc->expunge(&ibox->box, log->seq1,
- sc_context);
- }
- break;
- case RECORD_TYPE_FLAGS_CHANGED:
- if (first_flag_change == total_count) {
- first_flag_change = i;
- first_flag_log = log;
- first_flag_messages_count = messages;
- }
+ memset(&full_flags, 0, sizeof(full_flags));
+ while ((ret = mail_index_view_sync_next(ctx, &sync)) > 0) {
+ switch (sync.type) {
+ case MAIL_INDEX_SYNC_TYPE_APPEND:
+ appends = TRUE;
break;
- }
- }
-
- /* set synced messages count before flag changes break it */
- ibox->synced_messages_count = messages;
-
- /* now show the flags */
- messages = first_flag_messages_count;
- flags.custom_flags =
- mail_custom_flags_list_get(ibox->index->custom_flags);
- flags.custom_flags_count = MAIL_CUSTOM_FLAGS_COUNT;
-
- if (sc->update_flags == NULL) {
- /* don't bother going through, we're not printing them anyway */
- total_count = 0;
- }
-
- log = first_flag_log;
- for (i = first_flag_change; i < total_count; i++, log++) {
- if (i == count1)
- log = log2;
-
- if (log->seq1 > messages) {
- /* client doesn't know about this message yet */
- continue;
- }
-
- switch (log->type) {
- case RECORD_TYPE_EXPUNGE:
- messages -= (log->seq2 - log->seq1) + 1;
+ case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
+ /* later */
break;
- case RECORD_TYPE_FLAGS_CHANGED:
- rec = ibox->index->lookup_uid_range(ibox->index,
- log->uid1,
- log->uid2, &seq);
- while (rec != NULL && rec->uid <= log->uid2) {
- flags.flags = rec->msg_flags;
- if (rec->uid >= ibox->index->first_recent_uid)
- flags.flags |= MAIL_RECENT;
+ case MAIL_INDEX_SYNC_TYPE_FLAGS:
+ if (sc->update_flags == NULL)
+ break;
- /* \Deleted-hiding is useful when syncing just
- before doing EXPUNGE. */
- if ((flags.flags & MAIL_DELETED) == 0 ||
- !hide_deleted) {
- sc->update_flags(&ibox->box, seq,
- rec->uid, &flags,
- sc_context);
+ /* FIXME: hide the flag updates for expunged messages */
+ for (seq = sync.seq1; seq <= sync.seq2; seq++) {
+ if (mail_index_lookup(ibox->view,
+ seq, &rec) < 0) {
+ ret = -1;
+ break;
}
-
- seq++;
- rec = ibox->index->next(ibox->index, rec);
+ full_flags.flags = rec->flags; // FIXME
+ sc->update_flags(&ibox->box, seq,
+ &full_flags, sc_context);
}
break;
}
}
- /* mark synced */
- if (!mail_modifylog_mark_synced(ibox->index->modifylog))
- return mail_storage_set_index_error(ibox);
-
- return TRUE;
-}
-
-int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
-{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- int ret;
-
- if ((flags & MAILBOX_SYNC_FAST) == 0 ||
- ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
- ibox->sync_last_check = ioloop_time;
-
- if (!index_storage_sync_and_lock(ibox, FALSE, FALSE,
- MAIL_LOCK_UNLOCK))
- return FALSE;
- } else {
- /* check only modify log */
- if (!index_storage_lock(ibox, MAIL_LOCK_SHARED)) {
- (void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
- return FALSE;
+ if (sc->expunge != NULL) {
+ for (i = expunges_count*2; i > 0; i -= 2) {
+ for (seq = expunges[i-1]; seq >= expunges[i-2]; seq--)
+ sc->expunge(&ibox->box, seq, sc_context);
}
}
- /* FIXME: we could sync flags always, but expunges in the middle
- could make it a bit more difficult and slower */
- if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0 ||
- mail_modifylog_get_expunge_count(ibox->index->modifylog) == 0)
- ret = index_storage_sync_modifylog(ibox, FALSE);
- else
- ret = TRUE;
+ mail_index_view_sync_end(ctx);
- index_storage_sync_size(ibox);
+ if (appends) {
+ new_count = mail_index_view_get_message_count(ibox->view);
+ sc->new_messages(&ibox->box, new_count, 0, sc_context);
+ }
- if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
- return FALSE;
+ if (ret < 0)
+ mail_storage_set_index_error(ibox);
+ mail_index_view_unlock(ibox->view);
return ret;
}
--- index-copy.c DELETED ---
--- index-expunge.c DELETED ---
--- index-expunge.h DELETED ---
--- index-messageset.c DELETED ---
--- index-messageset.h DELETED ---
--- index-update-flags.c DELETED ---
- Previous message: [dovecot-cvs] dovecot/src/lib-mail mail-types.h, NONE,
1.1 Makefile.am, 1.7, 1.8 message-parser.c, 1.50,
1.51 message-parser.h, 1.23, 1.24
- Next message: [dovecot-cvs] dovecot/src/lib-storage/register Makefile.am,1.1,1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list