annotate src/lib-storage/index/mbox/mbox-sync-rewrite.c @ 2955:d5ee1bbd15f0 HEAD

Fixed mbox corruption in certain situations. Added more asserts to catch similiar problems if there still happens to be any.
author Timo Sirainen <tss@iki.fi>
date Tue, 07 Dec 2004 22:26:00 +0200
parents d1bae4aa3f80
children 8ef9f3d640e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 #include "lib.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2 #include "buffer.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "istream.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "ostream.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "str.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "write-full.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "message-parser.h"
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
8 #include "mbox-storage.h"
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "mbox-sync-private.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "istream-raw-mbox.h"
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 int mbox_move(struct mbox_sync_context *sync_ctx,
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 uoff_t dest, uoff_t source, uoff_t size)
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 {
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 struct istream *input;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 struct ostream *output;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 off_t ret;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
19 i_assert(size < OFF_T_MAX);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
20
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
21 if (size == 0 || source == dest)
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
22 return 0;
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
23
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
24 istream_raw_mbox_flush(sync_ctx->input);
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
25
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 output = o_stream_create_file(sync_ctx->fd, default_pool, 4096, FALSE);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 i_stream_seek(sync_ctx->file_input, source);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 o_stream_seek(output, dest);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29
2633
a87abc14de35 Remove size==(uoff_t)-1 handling because it never happens.
Timo Sirainen <tss@iki.fi>
parents: 2476
diff changeset
30 input = i_stream_create_limit(default_pool, sync_ctx->file_input,
a87abc14de35 Remove size==(uoff_t)-1 handling because it never happens.
Timo Sirainen <tss@iki.fi>
parents: 2476
diff changeset
31 source, size);
a87abc14de35 Remove size==(uoff_t)-1 handling because it never happens.
Timo Sirainen <tss@iki.fi>
parents: 2476
diff changeset
32 ret = o_stream_send_istream(output, input);
a87abc14de35 Remove size==(uoff_t)-1 handling because it never happens.
Timo Sirainen <tss@iki.fi>
parents: 2476
diff changeset
33 i_stream_unref(input);
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
34
2748
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
35 if (ret == (off_t)size)
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
36 ret = 0;
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
37 else if (ret >= 0) {
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
38 mail_storage_set_critical(sync_ctx->ibox->box.storage,
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
39 "mbox_move(%"PRIuUOFF_T", %"PRIuUOFF_T", %"PRIuUOFF_T
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
40 ") moved only %"PRIuUOFF_T" bytes in mbox file %s",
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
41 dest, source, size, (uoff_t)ret, sync_ctx->ibox->path);
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
42 ret = -1;
a71c11890f34 Fixed error message
Timo Sirainen <tss@iki.fi>
parents: 2743
diff changeset
43 } else if (ret < 0) {
2124
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
44 errno = output->stream_errno;
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
45 mbox_set_syscall_error(sync_ctx->ibox,
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
46 "o_stream_send_istream()");
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
47 }
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
48
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
49 o_stream_unref(output);
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
50 return (int)ret;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
53 static int mbox_fill_space(struct mbox_sync_context *sync_ctx,
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
54 uoff_t offset, uoff_t size)
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
55 {
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
56 unsigned char space[1024];
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
57
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
58 memset(space, ' ', sizeof(space));
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
59 while (size > sizeof(space)) {
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
60 if (pwrite_full(sync_ctx->fd, space,
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
61 sizeof(space), offset) < 0) {
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
62 mbox_set_syscall_error(sync_ctx->ibox, "pwrite_full()");
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
63 return -1;
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
64 }
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
65 size -= sizeof(space);
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
66 }
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
67
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
68 if (pwrite_full(sync_ctx->fd, space, size, offset) < 0) {
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
69 mbox_set_syscall_error(sync_ctx->ibox, "pwrite_full()");
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
70 return -1;
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
71 }
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
72 return 0;
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
73 }
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
74
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
75 static void
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
76 mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx, size_t size)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
78 size_t data_size, pos, start_pos;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 const unsigned char *data;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 void *p;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
2146
3a33250e6a2d Complain if file isn't in mbox format. Complain if From-line wasn't found
Timo Sirainen <tss@iki.fi>
parents: 2126
diff changeset
82 i_assert(size < SSIZE_T_MAX);
3a33250e6a2d Complain if file isn't in mbox format. Complain if From-line wasn't found
Timo Sirainen <tss@iki.fi>
parents: 2126
diff changeset
83
2250
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
84 if (ctx->pseudo)
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
85 start_pos = ctx->hdr_pos[MBOX_HDR_X_IMAPBASE];
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
86 else {
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
87 /* Append at the end of X-Keywords header,
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
88 or X-UID if it doesn't exist */
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
89 start_pos = ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] != (size_t)-1 ?
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
90 ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] :
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
91 ctx->hdr_pos[MBOX_HDR_X_UID];
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
92 }
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
93 i_assert(start_pos != (size_t)-1);
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
95 data = str_data(ctx->header);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
96 data_size = str_len(ctx->header);
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
98 for (pos = start_pos; pos < data_size; pos++) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
99 if (data[pos] == '\n') {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
100 /* possibly continues in next line */
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
101 if (pos+1 == data_size || !IS_LWSP(data[pos+1]))
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
102 break;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
103 start_pos = pos+1;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
104 } else if (!IS_LWSP(data[pos])) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
105 start_pos = pos+1;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
106 }
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
107 }
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
108
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
109 /* pos points to end of header now, and start_pos to beginning
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
110 of whitespace. */
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
112 buffer_copy(ctx->header, pos + size,
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
113 ctx->header, pos, (size_t)-1);
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
114 p = buffer_get_space_unsafe(ctx->header, pos, size);
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
115 memset(p, ' ', size);
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
116
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 if (ctx->header_first_change > pos)
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 ctx->header_first_change = pos;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 ctx->header_last_change = (size_t)-1;
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
120
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
121 ctx->mail.space = (pos - start_pos) + size;
2955
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
122 ctx->mail.offset = ctx->hdr_offset;
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
123 if (ctx->mail.space > 0)
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
124 ctx->mail.offset += start_pos;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 static void mbox_sync_header_remove_space(struct mbox_sync_mail_context *ctx,
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
128 size_t start_pos, size_t *size)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 {
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 const unsigned char *data;
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
131 size_t data_size, pos, last_line_pos;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
133 /* find the end of the LWSP */
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 data = str_data(ctx->header);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 data_size = str_len(ctx->header);
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
136
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
137 for (pos = last_line_pos = start_pos; pos < data_size; pos++) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
138 if (data[pos] == '\n') {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
139 /* possibly continues in next line */
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
140 if (pos+1 == data_size || !IS_LWSP(data[pos+1])) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
141 data_size = pos;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 break;
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
143 }
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
144 last_line_pos = pos+1;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
145 } else if (!IS_LWSP(data[pos])) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
146 start_pos = last_line_pos = pos+1;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
150 if (start_pos == data_size)
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
151 return;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
152
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 /* and remove what we can */
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
154 if (ctx->header_first_change > start_pos)
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
155 ctx->header_first_change = start_pos;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
156 ctx->header_last_change = (size_t)-1;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
157
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
158 if (data_size - start_pos <= *size) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
159 /* remove it all */
2249
cb4dad60f6cd Several fixes for updating mbox. Recent changes also made it corrupt
Timo Sirainen <tss@iki.fi>
parents: 2214
diff changeset
160 mbox_sync_move_buffer(ctx, start_pos, 0, data_size - start_pos);
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
161 *size -= data_size - start_pos;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
162 return;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
163 }
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
164
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
165 /* we have more space than needed. since we're removing from
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
166 the beginning of header instead of end, we don't have to
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
167 worry about multiline-headers. */
2249
cb4dad60f6cd Several fixes for updating mbox. Recent changes also made it corrupt
Timo Sirainen <tss@iki.fi>
parents: 2214
diff changeset
168 mbox_sync_move_buffer(ctx, start_pos, 0, *size);
2176
Timo Sirainen <tss@iki.fi>
parents: 2164
diff changeset
169 if (last_line_pos <= start_pos + *size)
Timo Sirainen <tss@iki.fi>
parents: 2164
diff changeset
170 last_line_pos = start_pos;
Timo Sirainen <tss@iki.fi>
parents: 2164
diff changeset
171 else
Timo Sirainen <tss@iki.fi>
parents: 2164
diff changeset
172 last_line_pos -= *size;
Timo Sirainen <tss@iki.fi>
parents: 2164
diff changeset
173 data_size -= *size;
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
174
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
175 *size = 0;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
176
2643
664e9001183e signed vs. unsigned comparision fixes
Timo Sirainen <tss@iki.fi>
parents: 2633
diff changeset
177 if (ctx->mail.space < (off_t)(data_size - last_line_pos)) {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
178 ctx->mail.space = data_size - last_line_pos;
2955
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
179 ctx->mail.offset = ctx->hdr_offset;
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
180 if (ctx->mail.space > 0)
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
181 ctx->mail.offset += last_line_pos;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185 static void mbox_sync_headers_remove_space(struct mbox_sync_mail_context *ctx,
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 size_t size)
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187 {
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 static enum header_position space_positions[] = {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
189 MBOX_HDR_X_UID,
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 MBOX_HDR_X_KEYWORDS,
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 MBOX_HDR_X_IMAPBASE
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 };
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 enum header_position pos;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 int i;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
196 ctx->mail.space = 0;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
197 ctx->mail.offset = ctx->hdr_offset;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
198
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 for (i = 0; i < 3 && size > 0; i++) {
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 pos = space_positions[i];
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 if (ctx->hdr_pos[pos] != (size_t)-1) {
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 mbox_sync_header_remove_space(ctx, ctx->hdr_pos[pos],
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 &size);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 }
2153
53288223de6c Create X-Keywords header if possible.
Timo Sirainen <tss@iki.fi>
parents: 2151
diff changeset
206
53288223de6c Create X-Keywords header if possible.
Timo Sirainen <tss@iki.fi>
parents: 2151
diff changeset
207 /* FIXME: see if we could remove X-Keywords header completely */
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
210 int mbox_sync_try_rewrite(struct mbox_sync_mail_context *ctx, off_t move_diff)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211 {
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
212 size_t old_hdr_size, new_hdr_size;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213
1983
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
214 i_assert(ctx->sync_ctx->ibox->mbox_lock_type == F_WRLCK);
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
215
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 old_hdr_size = ctx->body_offset - ctx->hdr_offset;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217 new_hdr_size = str_len(ctx->header);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
219 if (new_hdr_size <= old_hdr_size) {
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
220 /* add space. note that we must call add_space() even if we're
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
221 not adding anything so mail.offset gets fixed. */
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
222 mbox_sync_headers_add_space(ctx, old_hdr_size - new_hdr_size);
1983
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
223 } else if (new_hdr_size > old_hdr_size) {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
224 /* try removing the space where we can */
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
225 mbox_sync_headers_remove_space(ctx,
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
226 new_hdr_size - old_hdr_size);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
227 new_hdr_size = str_len(ctx->header);
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
228
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
229 if (new_hdr_size <= old_hdr_size) {
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
230 /* good, we removed enough. */
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
231 i_assert(new_hdr_size == old_hdr_size);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
232 } else if (move_diff < 0 &&
2643
664e9001183e signed vs. unsigned comparision fixes
Timo Sirainen <tss@iki.fi>
parents: 2633
diff changeset
233 new_hdr_size - old_hdr_size <= (uoff_t)-move_diff) {
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
234 /* moving backwards - we can use the extra space from
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
235 it, just update expunged_space accordingly */
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
236 i_assert(ctx->mail.space == 0);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
237 i_assert(ctx->sync_ctx->expunged_space >=
2643
664e9001183e signed vs. unsigned comparision fixes
Timo Sirainen <tss@iki.fi>
parents: 2633
diff changeset
238 (off_t)(new_hdr_size - old_hdr_size));
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
239 ctx->sync_ctx->expunged_space -=
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
240 new_hdr_size - old_hdr_size;
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
241 } else {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
242 /* couldn't get enough space */
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
243 i_assert(ctx->mail.space == 0);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
244 ctx->mail.space =
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
245 -(ssize_t)(new_hdr_size - old_hdr_size);
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246 return 0;
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
247 }
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
250 i_assert(ctx->mail.space >= 0);
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
251
2126
57078e1f2bfc more syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 2124
diff changeset
252 if (ctx->header_first_change == (size_t)-1 && move_diff == 0) {
57078e1f2bfc more syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 2124
diff changeset
253 /* no changes actually. we get here if index sync record told
57078e1f2bfc more syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 2124
diff changeset
254 us to do something that was already there */
57078e1f2bfc more syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 2124
diff changeset
255 return 1;
57078e1f2bfc more syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 2124
diff changeset
256 }
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
257
2404
8ef002a26f1c Added struct message_header_line.middle and middle_len to contain the ':'
Timo Sirainen <tss@iki.fi>
parents: 2379
diff changeset
258 if (move_diff != 0) {
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
259 /* forget about partial write optimizations */
2107
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
260 ctx->header_first_change = 0;
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
261 ctx->header_last_change = 0;
8266299b92f5 expunging is somewhat working
Timo Sirainen <tss@iki.fi>
parents: 2041
diff changeset
262 }
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
263
1983
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
264 if (ctx->header_last_change != (size_t)-1 &&
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
265 ctx->header_last_change != 0)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
266 str_truncate(ctx->header, ctx->header_last_change);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
267
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
268 if (pwrite_full(ctx->sync_ctx->fd,
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
269 str_data(ctx->header) + ctx->header_first_change,
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
270 str_len(ctx->header) - ctx->header_first_change,
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
271 ctx->hdr_offset + ctx->header_first_change +
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
272 move_diff) < 0) {
2124
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
273 mbox_set_syscall_error(ctx->sync_ctx->ibox, "pwrite_full()");
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
274 return -1;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
275 }
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
276
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
277 if (ctx->sync_ctx->dest_first_mail) {
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
278 ctx->sync_ctx->base_uid_last =
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
279 ctx->sync_ctx->update_base_uid_last;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
280 ctx->sync_ctx->update_base_uid_last = 0;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
281 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
282
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
283 istream_raw_mbox_flush(ctx->sync_ctx->input);
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
284 return 1;
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285 }
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
286
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
287 static int mbox_sync_read_and_move(struct mbox_sync_context *sync_ctx,
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
288 struct mbox_sync_mail *mails,
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
289 uint32_t seq, uint32_t idx, uint32_t padding,
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
290 off_t move_diff, uoff_t expunged_space,
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
291 uoff_t end_offset, int first_nonexpunged)
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
292 {
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
293 struct mbox_sync_mail_context mail_ctx;
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
294 uint32_t old_prev_msg_uid;
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
295 uoff_t hdr_offset, offset, dest_offset;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
296 size_t need_space;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
297
2155
Timo Sirainen <tss@iki.fi>
parents: 2153
diff changeset
298 if (mbox_sync_seek(sync_ctx, mails[idx].from_offset) < 0)
Timo Sirainen <tss@iki.fi>
parents: 2153
diff changeset
299 return -1;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
300
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
301 memset(&mail_ctx, 0, sizeof(mail_ctx));
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
302 mail_ctx.sync_ctx = sync_ctx;
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
303 mail_ctx.seq = seq;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
304 mail_ctx.header = sync_ctx->header;
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
305 mail_ctx.uidl = sync_ctx->uidl;
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
306 str_truncate(mail_ctx.uidl, 0);
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
307
2476
bce342d816f0 sync fix
Timo Sirainen <tss@iki.fi>
parents: 2404
diff changeset
308 hdr_offset = istream_raw_mbox_get_header_offset(sync_ctx->input);
bce342d816f0 sync fix
Timo Sirainen <tss@iki.fi>
parents: 2404
diff changeset
309 mail_ctx.mail.offset = hdr_offset;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
310 mail_ctx.mail.body_size = mails[idx].body_size;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
311
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
312 /* mbox_sync_parse_next_mail() checks that UIDs are growing,
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
313 so we have to fool it. */
2146
3a33250e6a2d Complain if file isn't in mbox format. Complain if From-line wasn't found
Timo Sirainen <tss@iki.fi>
parents: 2126
diff changeset
314 old_prev_msg_uid = sync_ctx->prev_msg_uid;
2250
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
315 sync_ctx->prev_msg_uid = mails[idx].uid == 0 ? 0 : mails[idx].uid-1;
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
316 if (mails[idx].from_offset+1 - expunged_space != 0) {
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
317 sync_ctx->dest_first_mail = mails[idx].from_offset == 0;
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
318 } else {
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
319 /* we need to skip over the initial \n (it's already counted in
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
320 expunged_space) */
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
321 sync_ctx->dest_first_mail = TRUE;
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
322 mails[idx].from_offset++;
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
323 }
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
324
2214
c0b5573d76e3 fixes for From-line offset updating
Timo Sirainen <tss@iki.fi>
parents: 2190
diff changeset
325 mbox_sync_parse_next_mail(sync_ctx->input, &mail_ctx);
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
326 if (mails[idx].space != 0)
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
327 mbox_sync_update_header_from(&mail_ctx, &mails[idx]);
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
328 else {
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
329 /* updating might just try to add headers and mess up our
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
330 calculations completely. so only add the EOH here. */
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
331 if (mail_ctx.have_eoh)
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
332 str_append_c(mail_ctx.header, '\n');
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
333 }
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
334
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
335 if (first_nonexpunged && expunged_space > 0) {
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
336 /* move From-line (after parsing headers so we don't
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
337 overwrite them) */
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
338 if (mbox_move(sync_ctx, mails[idx].from_offset - expunged_space,
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
339 mails[idx].from_offset,
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
340 mails[idx].offset - mails[idx].from_offset) < 0)
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
341 return -1;
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
342 }
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
343
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
344 sync_ctx->prev_msg_uid = old_prev_msg_uid;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
345 sync_ctx->dest_first_mail = FALSE;
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
346
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
347 need_space = str_len(mail_ctx.header) - mail_ctx.mail.space -
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
348 (mail_ctx.body_offset - mail_ctx.hdr_offset);
2643
664e9001183e signed vs. unsigned comparision fixes
Timo Sirainen <tss@iki.fi>
parents: 2633
diff changeset
349 i_assert(need_space == (uoff_t)-mails[idx].space);
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
350
2699
Timo Sirainen <tss@iki.fi>
parents: 2693
diff changeset
351 if (mails[idx].space == 0) {
2693
ba7cd618d916 crashfix
Timo Sirainen <tss@iki.fi>
parents: 2687
diff changeset
352 /* don't touch spacing */
ba7cd618d916 crashfix
Timo Sirainen <tss@iki.fi>
parents: 2687
diff changeset
353 } else if (padding < (uoff_t)mail_ctx.mail.space) {
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
354 mbox_sync_headers_remove_space(&mail_ctx, mail_ctx.mail.space -
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
355 padding);
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
356 } else {
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
357 mbox_sync_headers_add_space(&mail_ctx, padding -
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
358 mail_ctx.mail.space);
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
359 }
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
360
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
361 /* move the body of this message and headers of next message forward,
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
362 then write the headers */
2146
3a33250e6a2d Complain if file isn't in mbox format. Complain if From-line wasn't found
Timo Sirainen <tss@iki.fi>
parents: 2126
diff changeset
363 offset = sync_ctx->input->v_offset;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
364 dest_offset = offset + move_diff;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
365 i_assert(offset <= end_offset);
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
366 if (mbox_move(sync_ctx, dest_offset, offset, end_offset - offset) < 0)
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
367 return -1;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
368
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
369 /* the header may actually be moved backwards if there was expunged
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
370 space which we wanted to remove */
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
371 i_assert(dest_offset >= str_len(mail_ctx.header));
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
372 dest_offset -= str_len(mail_ctx.header);
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
373 if (pwrite_full(sync_ctx->fd, str_data(mail_ctx.header),
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
374 str_len(mail_ctx.header), dest_offset) < 0) {
2124
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
375 mbox_set_syscall_error(sync_ctx->ibox, "pwrite_full()");
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
376 return -1;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
377 }
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
378
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
379 mails[idx].offset = dest_offset +
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
380 (mail_ctx.mail.offset - mail_ctx.hdr_offset);
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
381 mails[idx].space = mail_ctx.mail.space;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
382
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
383 if (mails[idx].from_offset == 0) {
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
384 sync_ctx->base_uid_last =
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
385 sync_ctx->update_base_uid_last;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
386 sync_ctx->update_base_uid_last = 0;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
387 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2176
diff changeset
388
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
389 return 0;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
390 }
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
391
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
392 int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx,
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
393 uoff_t end_offset, off_t move_diff, uoff_t extra_space,
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
394 uint32_t first_seq, uint32_t last_seq)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 {
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
396 struct mbox_sync_mail *mails;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
397 uoff_t offset, dest_offset, next_end_offset, next_move_diff;
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
398 uoff_t start_offset, expunged_space;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
399 uint32_t idx, first_nonexpunged_idx, padding_per_mail;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400 size_t size;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
401 int ret = 0;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
402
2829
d1bae4aa3f80 Expunge sync fix
Timo Sirainen <tss@iki.fi>
parents: 2807
diff changeset
403 i_assert(extra_space < OFF_T_MAX);
1983
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
404 i_assert(sync_ctx->ibox->mbox_lock_type == F_WRLCK);
933cab442392 mbox growing and locking works now
Timo Sirainen <tss@iki.fi>
parents: 1981
diff changeset
405
2124
24651c3ac7f3 major syncing code cleanups. the code finally looks almost readable. logic
Timo Sirainen <tss@iki.fi>
parents: 2119
diff changeset
406 mails = buffer_get_modifyable_data(sync_ctx->mails, &size);
2118
11febaee5e9b Save mbox offsets to index file using extra_records. Some other fixes.
Timo Sirainen <tss@iki.fi>
parents: 2111
diff changeset
407 i_assert(size / sizeof(*mails) == last_seq - first_seq + 1);
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
408
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
409 /* if there's expunges in mails[], we would get more correct balancing
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
410 by counting only them here. however, that might make us overwrite
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
411 data which hasn't yet been copied backwards. to avoid too much
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
412 complexity, we just leave all the rest of the extra space to first
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
413 mail */
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
414 idx = last_seq - first_seq + 1;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
415 padding_per_mail = extra_space / idx;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
416
2151
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
417 /* after expunge the next mail must have been missing space, or we
16287320d080 Several fixes in space/offset logic. Should be much more robust now.
Timo Sirainen <tss@iki.fi>
parents: 2146
diff changeset
418 would have moved it backwards already */
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
419 expunged_space = 0;
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
420 start_offset = mails[0].from_offset;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
421 for (first_nonexpunged_idx = 0;; first_nonexpunged_idx++) {
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
422 i_assert(first_nonexpunged_idx != idx);
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
423 if ((mails[first_nonexpunged_idx].flags & MBOX_EXPUNGED) == 0)
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
424 break;
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
425 expunged_space += mails[first_nonexpunged_idx].space;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
426 }
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
427 i_assert(mails[first_nonexpunged_idx].space < 0);
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
428
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
429 /* start moving backwards. */
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
430 while (idx > first_nonexpunged_idx) {
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
431 idx--;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
432 if (idx == first_nonexpunged_idx) {
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
433 /* give the rest of the extra space to first mail.
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
434 we might also have to move the mail backwards to
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
435 fill the expunged space */
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
436 padding_per_mail = move_diff + expunged_space +
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
437 mails[idx].space;
2164
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
438 }
Timo Sirainen <tss@iki.fi>
parents: 2155
diff changeset
439
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
440 next_end_offset = mails[idx].offset;
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
441
2250
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
442 if (mails[idx].space <= 0 &&
7b70a60c0f9d some fixes for handling pseudo headers.
Timo Sirainen <tss@iki.fi>
parents: 2249
diff changeset
443 (mails[idx].flags & MBOX_EXPUNGED) == 0) {
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
444 /* give space to this mail. end_offset is left to
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
445 contain this message's From-line (ie. below we
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
446 move only headers + body). */
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
447 int first_nonexpunged = idx == first_nonexpunged_idx;
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
448
2693
ba7cd618d916 crashfix
Timo Sirainen <tss@iki.fi>
parents: 2687
diff changeset
449 next_move_diff = -mails[idx].space;
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
450 if (mbox_sync_read_and_move(sync_ctx, mails,
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
451 first_seq + idx, idx,
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
452 padding_per_mail,
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
453 move_diff, expunged_space,
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
454 end_offset,
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
455 first_nonexpunged) < 0) {
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
456 ret = -1;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
457 break;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
458 }
2693
ba7cd618d916 crashfix
Timo Sirainen <tss@iki.fi>
parents: 2687
diff changeset
459 move_diff -= next_move_diff + mails[idx].space;
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
460 } else {
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
461 /* this mail provides more space. just move it forward
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
462 from the extra space offset and set end_offset to
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
463 point to beginning of extra space. that way the
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
464 header will be moved along with previous mail's
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
465 body.
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
466
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
467 if this is expunged mail, we're moving following
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
468 mail's From-line and maybe headers. */
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
469 offset = mails[idx].offset + mails[idx].space;
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
470 dest_offset = offset + move_diff;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
471 i_assert(offset <= end_offset);
2041
2240a38138db mbox syncing fixes
Timo Sirainen <tss@iki.fi>
parents: 1983
diff changeset
472 if (mbox_move(sync_ctx, dest_offset, offset,
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
473 end_offset - offset) < 0) {
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
474 ret = -1;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
475 break;
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
476 }
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
477
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
478 move_diff += mails[idx].space;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
479 if ((mails[idx].flags & MBOX_EXPUNGED) == 0) {
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
480 move_diff -= padding_per_mail;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
481 mails[idx].space = padding_per_mail;
2807
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
482
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
483 if (mbox_fill_space(sync_ctx, move_diff +
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
484 mails[idx].offset,
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
485 padding_per_mail) < 0) {
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
486 ret = -1;
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
487 break;
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
488 }
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
489 }
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
490 mails[idx].offset += move_diff;
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
491 }
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
492
2807
ad3fcccca2bb More expunge/rewrite fixes.
Timo Sirainen <tss@iki.fi>
parents: 2804
diff changeset
493 i_assert(move_diff >= 0 || idx == first_nonexpunged_idx);
2955
d5ee1bbd15f0 Fixed mbox corruption in certain situations. Added more asserts to catch
Timo Sirainen <tss@iki.fi>
parents: 2829
diff changeset
494 i_assert(next_end_offset <= end_offset);
2743
2cada6a7f3eb If rewriting began with expunged data areas, we didn't overwrite them which
Timo Sirainen <tss@iki.fi>
parents: 2699
diff changeset
495
2687
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
496 end_offset = next_end_offset;
482e1a1fe2ce Bringing some sanity into mbox rewrites. Fixes expunge crashes and reduces
Timo Sirainen <tss@iki.fi>
parents: 2662
diff changeset
497 mails[idx].from_offset += move_diff;
2266
d6001ee7815d Don't keep filling empty spaces which will be overwritten soon anyway. Major
Timo Sirainen <tss@iki.fi>
parents: 2250
diff changeset
498 }
2109
8c0168d19148 expunges should pretty much work now.
Timo Sirainen <tss@iki.fi>
parents: 2107
diff changeset
499
2804
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
500 i_assert(mails[idx].from_offset == start_offset);
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
501 i_assert(move_diff + (off_t)expunged_space >= 0);
c686e724aba6 rewrite fixes
Timo Sirainen <tss@iki.fi>
parents: 2748
diff changeset
502
1981
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
503 istream_raw_mbox_flush(sync_ctx->input);
eb282832fc75 mbox rewriting is almost working - the hard part is done.
Timo Sirainen <tss@iki.fi>
parents: 1978
diff changeset
504 return ret;
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
505 }