[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-sync-parse.c,
1.11, 1.12 mbox-sync-private.h, 1.12, 1.13 mbox-sync-rewrite.c,
1.14, 1.15 mbox-sync-update.c, 1.11, 1.12 mbox-sync.c, 1.27, 1.28
cras at procontrol.fi
cras at procontrol.fi
Fri Jun 18 00:29:23 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/lib-mail message-body-search.c, 1.16,
1.17 message-parser.c, 1.53, 1.54 message-parser.h, 1.24, 1.25
- Next message: [dovecot-cvs] dovecot/src/lib str.c,1.13,1.14 str.h,1.5,1.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv23859/lib-storage/index/mbox
Modified Files:
mbox-sync-parse.c mbox-sync-private.h mbox-sync-rewrite.c
mbox-sync-update.c mbox-sync.c
Log Message:
Several fixes in space/offset logic. Should be much more robust now.
Index: mbox-sync-parse.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mbox-sync-parse.c 14 Jun 2004 22:44:56 -0000 1.11
+++ mbox-sync-parse.c 17 Jun 2004 21:29:20 -0000 1.12
@@ -33,6 +33,32 @@
struct message_header_line *hdr);
};
+static void parse_trailing_whitespace(struct mbox_sync_mail_context *ctx,
+ struct message_header_line *hdr)
+{
+ size_t i, space = 0;
+
+ /* the value may contain newlines. we can't count whitespace before
+ and after it as a single contiguous whitespace block, as that may
+ get us into situation where removing whitespace goes eg.
+ " \n \n" -> " \n\n" which would then be treated as end of headers.
+
+ that could probably be avoided by being careful, but as newlines
+ should never be there (we don't generate them), it's not worth the
+ trouble. */
+
+ for (i = hdr->full_value_len; i > 0; i--) {
+ if (!IS_LWSP(hdr->full_value[i-1]))
+ break;
+ space++;
+ }
+
+ if (space > ctx->mail.space) {
+ ctx->mail.offset = hdr->full_value_offset + i;
+ ctx->mail.space = space;
+ }
+}
+
static enum mail_flags mbox_flag_find(struct mbox_flag_type *flags, char chr)
{
int i;
@@ -121,6 +147,7 @@
// FIXME: save keywords
+ parse_trailing_whitespace(ctx, hdr);
return TRUE;
}
@@ -130,7 +157,8 @@
if (!parse_x_imap_base(ctx, hdr))
return FALSE;
- /* this is the UW-IMAP style "FOLDER INTERNAL DATA" message. skip it. */
+ /* this is the c-client style "FOLDER INTERNAL DATA" message.
+ skip it. */
ctx->pseudo = TRUE;
return TRUE;
}
@@ -138,22 +166,10 @@
static int parse_x_keywords(struct mbox_sync_mail_context *ctx,
struct message_header_line *hdr)
{
- size_t i, space = 0;
-
- for (i = hdr->full_value_len; i > 0; i--) {
- if (!IS_LWSP_LF(hdr->full_value[i-1]))
- break;
- space++;
- }
-
- if (space > ctx->mail.space) {
- ctx->mail.offset = hdr->full_value_offset + i;
- ctx->mail.space = space;
- }
-
// FIXME: parse them
ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
+ parse_trailing_whitespace(ctx, hdr);
return TRUE;
}
@@ -161,7 +177,7 @@
struct message_header_line *hdr)
{
uint32_t value = 0;
- size_t i, space_pos, extra_space = 0;
+ size_t i;
if (ctx->mail.uid != 0) {
/* duplicate */
@@ -174,15 +190,6 @@
value = value*10 + (hdr->full_value[i] - '0');
}
- space_pos = i;
- for (; i < hdr->full_value_len; i++) {
- if (!IS_LWSP_LF(hdr->full_value[i])) {
- /* broken value */
- return FALSE;
- }
- extra_space++;
- }
-
if (value >= ctx->sync_ctx->next_uid) {
/* next_uid broken - fix it */
ctx->sync_ctx->next_uid = value+1;
@@ -192,17 +199,20 @@
/* broken - UIDs must be growing */
return FALSE;
}
- ctx->sync_ctx->prev_msg_uid = value;
-
- ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
ctx->mail.uid = value;
- if (extra_space != 0 && ctx->mail.space == 0) {
- /* set it only if X-Keywords hasn't been seen. spaces in X-UID
- should be removed when writing X-Keywords. */
- ctx->mail.offset = hdr->full_value_offset + space_pos;
- ctx->mail.space = extra_space;
+ ctx->sync_ctx->prev_msg_uid = value;
+
+ if (ctx->sync_ctx->dest_first_mail && !ctx->seen_imapbase) {
+ /* everything was good, except we can't have X-UID before
+ X-IMAPbase header (to keep c-client compatibility). keep
+ the UID, but when we're rewriting this makes sure the
+ X-UID is appended after X-IMAPbase. */
+ return FALSE;
}
+
+ ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
+ parse_trailing_whitespace(ctx, hdr);
return TRUE;
}
@@ -279,7 +289,7 @@
str_truncate(ctx->header, 0);
line_start_pos = 0;
- hdr_ctx = message_parse_header_init(input, NULL);
+ hdr_ctx = message_parse_header_init(input, NULL, FALSE);
while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) {
if (hdr->eoh) {
ctx->have_eoh = TRUE;
@@ -292,6 +302,18 @@
str_append(ctx->header, ": ");
}
+ if (ctx->header_first_change == (size_t)-1 &&
+ hdr->full_value_offset != str_len(ctx->header)) {
+ /* whitespaces around ':' are non-standard. either
+ there's whitespace before ':' or none after.
+ if we're going to rewrite this message, we can't
+ do it partially from here after as offsets won't
+ match. this shouldn't happen pretty much ever, so
+ don't try to optimize this - just rewrite the whole
+ thing. */
+ ctx->no_partial_rewrite = TRUE;
+ }
+
func = header_func_find(hdr->name);
if (func != NULL) {
if (hdr->continues)
@@ -318,7 +340,7 @@
message_parse_header_deinit(hdr_ctx);
if ((ctx->seq == 1 && sync_ctx->base_uid_validity == 0) ||
- (ctx->seq > 1 && sync_ctx->first_uid == 0)) {
+ (ctx->seq > 1 && sync_ctx->dest_first_mail)) {
/* missing X-IMAPbase */
ctx->need_rewrite = TRUE;
}
Index: mbox-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- mbox-sync-private.h 15 Jun 2004 01:15:44 -0000 1.12
+++ mbox-sync-private.h 17 Jun 2004 21:29:20 -0000 1.13
@@ -31,9 +31,19 @@
keywords_mask_t keywords;
uoff_t from_offset;
- uoff_t offset; /* if space <= 0, points to beginning */
- off_t space;
uoff_t body_size;
+
+ /* following variables have a bit overloaded functionality:
+
+ a) space <= 0 : offset points to beginning of headers. space is the
+ amount of space missing that is required to be able to rewrite
+ the headers
+ b) space > 0 : offset points to beginning of whitespace that can
+ be removed. space is the amount of data that can be removed from
+ there. note that the message may contain more whitespace
+ elsewhere. */
+ uoff_t offset;
+ off_t space;
};
struct mbox_sync_mail_context {
@@ -52,6 +62,7 @@
unsigned int have_eoh:1;
unsigned int need_rewrite:1;
+ unsigned int no_partial_rewrite:1;
unsigned int seen_imapbase:1;
unsigned int pseudo:1;
unsigned int updated:1;
@@ -78,9 +89,11 @@
buffer_t *mails, *syncs;
struct mail_index_sync_rec sync_rec;
- uint32_t prev_msg_uid, next_uid, first_uid;
+ uint32_t prev_msg_uid, next_uid;
uint32_t seq, idx_seq, need_space_seq;
off_t expunged_space, space_diff;
+
+ unsigned int dest_first_mail:1;
};
int mbox_sync(struct index_mailbox *ibox, int last_commit, int lock);
Index: mbox-sync-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-rewrite.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mbox-sync-rewrite.c 16 Jun 2004 05:38:23 -0000 1.14
+++ mbox-sync-rewrite.c 17 Jun 2004 21:29:20 -0000 1.15
@@ -16,6 +16,8 @@
struct ostream *output;
off_t ret;
+ i_assert(size < OFF_T_MAX);
+
if (size == 0 || source == dest)
return 0;
@@ -50,7 +52,7 @@
static void mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx,
size_t size)
{
- size_t data_size, pos;
+ size_t data_size, pos, start_pos;
const unsigned char *data;
void *p;
@@ -58,24 +60,33 @@
/* Append at the end of X-Keywords header,
or X-UID if it doesn't exist */
- pos = ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] != (size_t)-1 ?
+ start_pos = ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] != (size_t)-1 ?
ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] :
ctx->hdr_pos[MBOX_HDR_X_UID];
- data = buffer_get_data(ctx->header, &data_size);
- while (pos < data_size && data[pos] != '\n')
- pos++;
+ data = str_data(ctx->header);
+ data_size = str_len(ctx->header);
+
+ for (pos = start_pos; pos < data_size; pos++) {
+ if (data[pos] == '\n') {
+ /* possibly continues in next line */
+ if (pos+1 == data_size || !IS_LWSP(data[pos+1]))
+ break;
+ start_pos = pos+1;
+ } else if (!IS_LWSP(data[pos])) {
+ start_pos = pos+1;
+ }
+ }
+ /* pos points to end of headers now, and start_pos to beginning of
+ whitespace. */
buffer_copy(ctx->header, pos + size,
ctx->header, pos, (size_t)-1);
p = buffer_get_space_unsafe(ctx->header, pos, size);
memset(p, ' ', size);
- ctx->mail.offset = ctx->hdr_offset + pos;
- if (ctx->mail.space < 0)
- ctx->mail.space = size;
- else
- ctx->mail.space += size;
+ ctx->mail.offset = ctx->hdr_offset + start_pos;
+ ctx->mail.space = (pos - start_pos) + size;
if (ctx->header_first_change > pos)
ctx->header_first_change = pos;
@@ -83,39 +94,56 @@
}
static void mbox_sync_header_remove_space(struct mbox_sync_mail_context *ctx,
- size_t pos, size_t *size)
+ size_t start_pos, size_t *size)
{
const unsigned char *data;
- size_t data_size, end, nonspace;
+ size_t data_size, pos, last_line_pos;
- /* find the end of the lwsp */
- nonspace = pos-1;
+ /* find the end of the LWSP */
data = str_data(ctx->header);
data_size = str_len(ctx->header);
- for (end = pos; end < data_size; end++) {
- if (data[end] == '\n') {
- if (end+1 == data_size || !IS_LWSP(data[end+1]))
+
+ for (pos = last_line_pos = start_pos; pos < data_size; pos++) {
+ if (data[pos] == '\n') {
+ /* possibly continues in next line */
+ if (pos+1 == data_size || !IS_LWSP(data[pos+1])) {
+ data_size = pos;
break;
- } else {
- if (!IS_LWSP(data[end]))
- nonspace = end;
+ }
+ last_line_pos = pos+1;
+ } else if (!IS_LWSP(data[pos])) {
+ start_pos = last_line_pos = pos+1;
}
}
+ if (start_pos == data_size)
+ return;
+
/* and remove what we can */
- nonspace++;
- if (end-nonspace < *size) {
- str_delete(ctx->header, nonspace, end-nonspace);
- *size -= end-nonspace;
- } else {
- str_delete(ctx->header, nonspace, *size);
- end -= *size;
- *size = 0;
+ if (ctx->header_first_change > start_pos)
+ ctx->header_first_change = start_pos;
+ ctx->header_last_change = (size_t)-1;
- if (ctx->mail.space < end-nonspace) {
- ctx->mail.space = end-nonspace;
- ctx->mail.offset = ctx->hdr_offset + nonspace;
- }
+ if (data_size - start_pos <= *size) {
+ /* remove it all */
+ str_delete(ctx->header, start_pos, data_size - start_pos);
+ *size -= data_size - start_pos;
+ return;
+ }
+
+ /* we have more space than needed. since we're removing from
+ the beginning of header instead of end, we don't have to
+ worry about multiline-headers. */
+ str_delete(ctx->header, start_pos, *size);
+ last_line_pos = last_line_pos <= *size ?
+ start_pos : last_line_pos - *size;
+
+ data_size -= *size;
+ *size = 0;
+
+ if (ctx->mail.space < data_size - last_line_pos) {
+ ctx->mail.space = data_size - last_line_pos;
+ ctx->mail.offset = ctx->hdr_offset + last_line_pos;
}
}
@@ -123,35 +151,28 @@
size_t size)
{
static enum header_position space_positions[] = {
- MBOX_HDR_X_KEYWORDS,
MBOX_HDR_X_UID,
+ MBOX_HDR_X_KEYWORDS,
MBOX_HDR_X_IMAPBASE
};
enum header_position pos;
int i;
- ctx->header_last_change = (size_t)-1;
-
ctx->mail.space = 0;
ctx->mail.offset = ctx->hdr_offset;
for (i = 0; i < 3 && size > 0; i++) {
pos = space_positions[i];
if (ctx->hdr_pos[pos] != (size_t)-1) {
- if (ctx->header_first_change > ctx->hdr_pos[pos])
- ctx->header_first_change = ctx->hdr_pos[pos];
mbox_sync_header_remove_space(ctx, ctx->hdr_pos[pos],
&size);
}
}
-
- i_assert(size == 0);
}
int mbox_sync_try_rewrite(struct mbox_sync_mail_context *ctx, off_t move_diff)
{
size_t old_hdr_size, new_hdr_size;
- const unsigned char *data;
i_assert(ctx->sync_ctx->ibox->mbox_lock_type == F_WRLCK);
@@ -162,43 +183,53 @@
if (new_hdr_size < old_hdr_size) {
mbox_sync_headers_add_space(ctx, old_hdr_size - new_hdr_size);
} else if (new_hdr_size > old_hdr_size) {
- size_t needed = new_hdr_size - old_hdr_size;
+ /* try removing the space where we can */
+ mbox_sync_headers_remove_space(ctx,
+ new_hdr_size - old_hdr_size);
+ new_hdr_size = str_len(ctx->header);
- if (ctx->mail.space >= 0)
- mbox_sync_headers_remove_space(ctx, needed);
- else if (move_diff < 0 && needed <= -move_diff) {
+ if (new_hdr_size <= old_hdr_size) {
+ /* good, we removed enough. */
+ i_assert(new_hdr_size == old_hdr_size);
+ } else if (move_diff < 0 &&
+ new_hdr_size - old_hdr_size <= -move_diff) {
/* moving backwards - we can use the extra space from
it, just update expunged_space accordingly */
- i_assert(ctx->sync_ctx->expunged_space >= needed);
- ctx->sync_ctx->expunged_space -= needed;
+ i_assert(ctx->mail.space == 0);
+ i_assert(ctx->sync_ctx->expunged_space >=
+ new_hdr_size - old_hdr_size);
+ ctx->sync_ctx->expunged_space -=
+ new_hdr_size - old_hdr_size;
} else {
+ /* couldn't get enough space */
+ i_assert(ctx->mail.space == 0);
+ ctx->mail.space =
+ -(ssize_t)(new_hdr_size - old_hdr_size);
return 0;
}
}
+ i_assert(ctx->mail.space >= 0);
+
if (ctx->header_first_change == (size_t)-1 && move_diff == 0) {
/* no changes actually. we get here if index sync record told
us to do something that was already there */
return 1;
}
- if (move_diff != 0) {
- /* we're moving the header, forget about partial write
- optimizations */
+ if (move_diff != 0 || ctx->no_partial_rewrite) {
+ /* forget about partial write optimizations */
ctx->header_first_change = 0;
ctx->header_last_change = 0;
}
- /* FIXME: last_change should rather just tell if we want to truncate
- to beginning of extra whitespace */
if (ctx->header_last_change != (size_t)-1 &&
ctx->header_last_change != 0)
str_truncate(ctx->header, ctx->header_last_change);
- data = str_data(ctx->header);
- new_hdr_size = str_len(ctx->header);
- if (pwrite_full(ctx->sync_ctx->fd, data + ctx->header_first_change,
- new_hdr_size - ctx->header_first_change,
+ if (pwrite_full(ctx->sync_ctx->fd,
+ str_data(ctx->header) + ctx->header_first_change,
+ str_len(ctx->header) - ctx->header_first_change,
ctx->hdr_offset + move_diff +
ctx->header_first_change) < 0) {
mbox_set_syscall_error(ctx->sync_ctx->ibox, "pwrite_full()");
@@ -232,6 +263,7 @@
so we have to fool it. */
old_prev_msg_uid = sync_ctx->prev_msg_uid;
sync_ctx->prev_msg_uid = mails[idx].uid-1;
+ sync_ctx->dest_first_mail = seq == 1;
mbox_sync_parse_next_mail(sync_ctx->input, &mail_ctx, TRUE);
if (mails[idx].space != 0)
@@ -243,8 +275,13 @@
str_append_c(mail_ctx.header, '\n');
}
- i_assert(mail_ctx.mail.space == mails[idx].space);
sync_ctx->prev_msg_uid = old_prev_msg_uid;
+ sync_ctx->dest_first_mail = FALSE;
+
+ mail_ctx.mail.space =
+ -(ssize_t)(str_len(mail_ctx.header) -
+ (mail_ctx.body_offset - mail_ctx.hdr_offset));
+ i_assert(mail_ctx.mail.space == mails[idx].space);
if (mail_ctx.mail.space <= 0)
mbox_sync_headers_add_space(&mail_ctx, extra_per_mail);
@@ -301,11 +338,13 @@
so we have to fool it. */
old_prev_msg_uid = sync_ctx->prev_msg_uid;
sync_ctx->prev_msg_uid = mails[idx].uid-1;
+ sync_ctx->dest_first_mail = seq == 1;
mbox_sync_parse_next_mail(sync_ctx->input, &mail_ctx, TRUE);
mbox_sync_update_header_from(&mail_ctx, &mails[idx]);
sync_ctx->prev_msg_uid = old_prev_msg_uid;
+ sync_ctx->dest_first_mail = FALSE;
mbox_sync_headers_add_space(&mail_ctx,end_offset - start_offset);
@@ -347,12 +386,10 @@
i_assert(mails[idx].space >= 0);
end_offset = mails[idx].offset + mails[idx].space;
- i_assert(mails[0].space < 0 || mails[0].uid == 0);
- start_offset = mails[0].offset;
-
/* after expunge the next mail must have been missing space, or we
would have moved it backwards already */
- i_assert(mails[0].uid != 0 || mails[1].space < 0);
+ i_assert(mails[0].space < 0 || mails[0].uid == 0);
+ start_offset = mails[0].offset;
/* start moving backwards */
do {
Index: mbox-sync-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-update.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mbox-sync-update.c 16 Jun 2004 05:38:23 -0000 1.11
+++ mbox-sync-update.c 17 Jun 2004 21:29:20 -0000 1.12
@@ -19,28 +19,30 @@
static void mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
size_t pos, size_t need, size_t have)
{
+ ssize_t diff = (ssize_t)need - (ssize_t)have;
int i;
- if (need == have) {
+ if (diff == 0) {
if (ctx->header_last_change < pos + have ||
ctx->header_last_change == (size_t)-1)
ctx->header_last_change = pos + have;
} else {
+ /* FIXME: if (diff < ctx->space && pos < ctx->offset) then
+ move the data only up to space offset and give/take the
+ space from there. update header_last_change accordingly. */
ctx->header_last_change = (size_t)-1;
for (i = 0; i < MBOX_HDR_COUNT; i++) {
if (ctx->hdr_pos[i] > pos &&
ctx->hdr_pos[i] != (size_t)-1)
- ctx->hdr_pos[i] += need - have;
+ ctx->hdr_pos[i] += diff;
}
- if (need < have) {
- str_delete(ctx->header, pos, have-need);
- ctx->mail.space += have - need;
- } else {
+ if (diff < 0)
+ str_delete(ctx->header, pos, -diff);
+ else {
ctx->header_last_change = (size_t)-1;
- buffer_copy(ctx->header, pos + (need-have),
+ buffer_copy(ctx->header, pos + diff,
ctx->header, pos, (size_t)-1);
- ctx->mail.space -= need - have;
}
}
}
@@ -111,7 +113,7 @@
str_append_c(ctx->header, '\n');
}
- if (ctx->mail.uid == ctx->sync_ctx->first_uid &&
+ if (ctx->sync_ctx->dest_first_mail &&
ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1) {
if (ctx->sync_ctx->base_uid_validity == 0) {
ctx->sync_ctx->base_uid_validity =
@@ -174,16 +176,6 @@
if (ctx->header_first_change == (size_t)-1)
ctx->header_first_change = new_hdr_size;
ctx->header_last_change = (size_t)-1;
- ctx->mail.space -= str_len(ctx->header) - new_hdr_size;
- if (ctx->mail.space > 0) {
- /* we should rewrite this header, so offset
- must be broken if it's used anymore. */
- ctx->mail.offset = (uoff_t)-1;
- } else {
- /* we don't have enough space for this header, change
- offset to point back to beginning of headers */
- ctx->mail.offset = ctx->hdr_offset;
- }
}
if (ctx->have_eoh)
@@ -216,7 +208,7 @@
const char *p, *hdr;
size_t pos;
- if (ctx->mail.uid != ctx->sync_ctx->first_uid ||
+ if (ctx->sync_ctx->dest_first_mail ||
ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1 ||
ctx->sync_ctx->update_base_uid_last == 0 ||
ctx->sync_ctx->update_base_uid_last < ctx->sync_ctx->base_uid_last)
Index: mbox-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- mbox-sync.c 16 Jun 2004 06:09:31 -0000 1.27
+++ mbox-sync.c 17 Jun 2004 21:29:20 -0000 1.28
@@ -188,7 +188,7 @@
mail_ctx->mail.offset =
istream_raw_mbox_get_header_offset(sync_ctx->input);
- if (mail_ctx->seq > 1 && sync_ctx->first_uid == mail_ctx->mail.uid) {
+ if (mail_ctx->seq > 1 && sync_ctx->dest_first_mail) {
/* First message was expunged and this is the next one.
Skip \n header */
mail_ctx->from_offset++;
@@ -489,7 +489,7 @@
mail_ctx->mail.body_size;
mail_ctx->mail.body_size = 0;
- if (mail_ctx->sync_ctx->seq == 1) {
+ if (mail_ctx->sync_ctx->dest_first_mail) {
/* expunging first message, fix space to contain next
message's \n header too since it will be removed. */
mail_ctx->mail.space++;
@@ -505,9 +505,6 @@
off_t move_diff;
int ret;
- if (sync_ctx->first_uid == 0)
- sync_ctx->first_uid = mail_ctx->mail.uid;
-
if (sync_ctx->ibox->mbox_readonly)
return 0;
@@ -627,6 +624,7 @@
/* set to -1, since they're always increased later */
sync_ctx->seq = sync_ctx->idx_seq = seq-1;
+ sync_ctx->dest_first_mail = sync_ctx->seq == 0;
if (istream_raw_mbox_seek(sync_ctx->input, offset) < 0) {
mail_storage_set_critical(sync_ctx->ibox->box.storage,
"Cached message offset %s is invalid for mbox file %s",
@@ -654,31 +652,31 @@
"Mailbox isn't a valid mbox file");
return -1;
}
+ sync_ctx->dest_first_mail = TRUE;
} else {
/* we sync only what we need to. jump to first record that
needs updating */
const struct mail_index_sync_rec *sync_rec;
+ size_t size;
- if (buffer_get_used_size(sync_ctx->syncs) == 0) {
+ if (buffer_get_used_size(sync_ctx->syncs) == 0 &&
+ sync_ctx->sync_rec.uid1 == 0) {
if (mbox_sync_read_index_syncs(sync_ctx, 1,
&expunged) < 0)
return -1;
- if (buffer_get_used_size(sync_ctx->syncs) == 0) {
+ if (buffer_get_used_size(sync_ctx->syncs) == 0 &&
+ sync_ctx->sync_rec.uid1 == 0) {
/* nothing to do */
return 0;
}
}
- sync_rec = buffer_get_data(sync_ctx->syncs, NULL);
+ sync_rec = buffer_get_data(sync_ctx->syncs, &size);
+ if (size == 0)
+ sync_rec = &sync_ctx->sync_rec;
if (mbox_sync_seek_to_uid(sync_ctx, sync_rec->uid1) < 0)
return -1;
-
- if (sync_ctx->seq > 0) {
- if (mail_index_lookup_uid(sync_ctx->sync_view, 1,
- &sync_ctx->first_uid) < 0)
- return -1;
- }
}
while ((ret = mbox_sync_read_next_mail(sync_ctx, mail_ctx)) > 0) {
@@ -688,9 +686,10 @@
if (mbox_sync_read_index_syncs(sync_ctx, uid, &expunged) < 0)
return -1;
- if (!expunged)
+ if (!expunged) {
ret = mbox_sync_handle_header(mail_ctx);
- else {
+ sync_ctx->dest_first_mail = FALSE;
+ } else {
mail_ctx->mail.uid = 0;
ret = mbox_sync_handle_expunge(mail_ctx);
}
@@ -880,7 +879,7 @@
sync_ctx->base_uid_last = 0;
sync_ctx->next_uid = 1;
- sync_ctx->prev_msg_uid = sync_ctx->first_uid = 0;
+ sync_ctx->prev_msg_uid = 0;
sync_ctx->seq = sync_ctx->idx_seq = 0;
}
- Previous message: [dovecot-cvs] dovecot/src/lib-mail message-body-search.c, 1.16,
1.17 message-parser.c, 1.53, 1.54 message-parser.h, 1.24, 1.25
- Next message: [dovecot-cvs] dovecot/src/lib str.c,1.13,1.14 str.h,1.5,1.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list