Mercurial > dovecot > original-hg > dovecot-1.2
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 |
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 | 21 if (size == 0 || source == dest) |
22 return 0; | |
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 | 34 |
2748 | 35 if (ret == (off_t)size) |
36 ret = 0; | |
37 else if (ret >= 0) { | |
38 mail_storage_set_critical(sync_ctx->ibox->box.storage, | |
39 "mbox_move(%"PRIuUOFF_T", %"PRIuUOFF_T", %"PRIuUOFF_T | |
40 ") moved only %"PRIuUOFF_T" bytes in mbox file %s", | |
41 dest, source, size, (uoff_t)ret, sync_ctx->ibox->path); | |
42 ret = -1; | |
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 | 49 o_stream_unref(output); |
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 | 53 static int mbox_fill_space(struct mbox_sync_context *sync_ctx, |
54 uoff_t offset, uoff_t size) | |
55 { | |
56 unsigned char space[1024]; | |
57 | |
58 memset(space, ' ', sizeof(space)); | |
59 while (size > sizeof(space)) { | |
60 if (pwrite_full(sync_ctx->fd, space, | |
61 sizeof(space), offset) < 0) { | |
62 mbox_set_syscall_error(sync_ctx->ibox, "pwrite_full()"); | |
63 return -1; | |
64 } | |
65 size -= sizeof(space); | |
66 } | |
67 | |
68 if (pwrite_full(sync_ctx->fd, space, size, offset) < 0) { | |
69 mbox_set_syscall_error(sync_ctx->ibox, "pwrite_full()"); | |
70 return -1; | |
71 } | |
72 return 0; | |
73 } | |
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 | 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 | 169 if (last_line_pos <= start_pos + *size) |
170 last_line_pos = start_pos; | |
171 else | |
172 last_line_pos -= *size; | |
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 | 219 if (new_hdr_size <= old_hdr_size) { |
220 /* add space. note that we must call add_space() even if we're | |
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 | 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 | 234 /* moving backwards - we can use the extra space from |
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 | 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 | 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 | 252 if (ctx->header_first_change == (size_t)-1 && move_diff == 0) { |
253 /* no changes actually. we get here if index sync record told | |
254 us to do something that was already there */ | |
255 return 1; | |
256 } | |
2107 | 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 | 260 ctx->header_first_change = 0; |
261 ctx->header_last_change = 0; | |
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 | 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 | 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 | 298 if (mbox_sync_seek(sync_ctx, mails[idx].from_offset) < 0) |
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 | 308 hdr_offset = istream_raw_mbox_get_header_offset(sync_ctx->input); |
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 | 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 | 338 if (mbox_move(sync_ctx, mails[idx].from_offset - expunged_space, |
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 | 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 | 351 if (mails[idx].space == 0) { |
2693 | 352 /* don't touch spacing */ |
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 | 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 | 361 /* move the body of this message and headers of next message forward, |
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 | 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 | 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 | 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 | 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 | 428 |
429 /* start moving backwards. */ | |
2804 | 430 while (idx > first_nonexpunged_idx) { |
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 | 438 } |
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 | 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 | 444 /* give space to this mail. end_offset is left to |
445 contain this message's From-line (ie. below we | |
446 move only headers + body). */ | |
447 int first_nonexpunged = idx == first_nonexpunged_idx; | |
448 | |
2693 | 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 | 454 end_offset, |
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 | 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 | 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 | 482 |
483 if (mbox_fill_space(sync_ctx, move_diff + | |
484 mails[idx].offset, | |
485 padding_per_mail) < 0) { | |
486 ret = -1; | |
487 break; | |
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 | 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 | 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 | 500 i_assert(mails[idx].from_offset == start_offset); |
501 i_assert(move_diff + (off_t)expunged_space >= 0); | |
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 } |