Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-index/mbox/mbox-rewrite.c @ 765:553f050c8313 HEAD
Added buffer API. Point is to hide all buffer writing behind this API which
verifies that nothing overflows. Much better than doing the same checks all
around the code, even if it is slightly slower.
Buffer reading is still mostly done directly, that isn't such a big security
risk and I can't think of a reasonable API for it anyway.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 08 Dec 2002 07:23:07 +0200 |
parents | f57c52738f90 |
children | 5ac361acb316 |
rev | line source |
---|---|
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (C) 2002 Timo Sirainen */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
4 #include "istream.h" |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
5 #include "ostream.h" |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "temp-string.h" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "write-full.h" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include "mbox-index.h" |
298
5509d87fe68b
mbox locking changes. support read-locking now. there's still problems
Timo Sirainen <tss@iki.fi>
parents:
297
diff
changeset
|
9 #include "mbox-lock.h" |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "mail-index-util.h" |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
11 #include "mail-custom-flags.h" |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include <stdio.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include <stdlib.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 #include <unistd.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 #include <fcntl.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 typedef struct { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
19 OStream *output; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 int failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
22 uoff_t content_length; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 unsigned int seq; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 unsigned int msg_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 const char **custom_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 unsigned int uid_validity; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 unsigned int uid_last; |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
29 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
30 unsigned int ximapbase_found:1; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
31 unsigned int xkeywords_found:1; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
32 unsigned int status_found:1; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
33 unsigned int xstatus_found:1; |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
34 unsigned int content_length_found:1; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 } MboxRewriteContext; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 /* Remove dirty flag from all messages */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 static void reset_dirty_flags(MailIndex *index) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 MailIndexRecord *rec; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 rec = index->lookup(index, 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 while (rec != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 rec->index_flags &= ~INDEX_MAIL_FLAG_DIRTY; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 rec = index->next(index, rec); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 } |
209
d85a6898bf39
Don't rewrite mbox if no flags were changed.
Timo Sirainen <tss@iki.fi>
parents:
194
diff
changeset
|
47 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
48 index->header->flags &= ~(MAIL_INDEX_FLAG_DIRTY_MESSAGES | |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
49 MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
52 static int mbox_write(MailIndex *index, IStream *input, OStream *output, |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 uoff_t end_offset) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
55 uoff_t old_limit; |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
56 int failed; |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
57 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
58 i_assert(input->v_offset <= end_offset); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
60 old_limit = input->v_limit; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
61 i_stream_set_read_limit(input, end_offset); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
62 if (o_stream_send_istream(output, input) < 0) { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
63 index_set_error(index, "Error rewriting mbox file %s: %s", |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
64 index->mbox_path, |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
65 strerror(output->stream_errno)); |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
66 failed = TRUE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
67 } else if (input->v_offset < end_offset) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 /* fsck should have noticed it.. */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 index_set_error(index, "Error rewriting mbox file %s: " |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 "Unexpected end of file", index->mbox_path); |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
71 failed = TRUE; |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
72 } else { |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
73 failed = FALSE; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
76 i_stream_set_read_limit(input, old_limit); |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
77 return !failed; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
80 static int mbox_write_ximapbase(MboxRewriteContext *ctx) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
81 { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
82 const char *str; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
83 int i; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
84 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
85 str = t_strdup_printf("X-IMAPbase: %u %u", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
86 ctx->uid_validity, ctx->uid_last); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
87 if (o_stream_send(ctx->output, str, strlen(str)) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
88 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
89 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
90 for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
91 if (ctx->custom_flags[i] != NULL) { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
92 if (o_stream_send(ctx->output, " ", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
93 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
94 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
95 if (o_stream_send(ctx->output, ctx->custom_flags[i], |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
96 strlen(ctx->custom_flags[i])) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
97 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
98 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
99 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
100 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
101 if (o_stream_send(ctx->output, "\n", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
102 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
103 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
104 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
105 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
106 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
107 static int mbox_write_xkeywords(MboxRewriteContext *ctx, const char *x_keywords) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
108 { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
109 unsigned int field; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
110 int i; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
111 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
112 if ((ctx->msg_flags & MAIL_CUSTOM_FLAGS_MASK) == 0 && |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
113 x_keywords == NULL) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
114 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
115 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
116 if (o_stream_send(ctx->output, "X-Keywords:", 11) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
117 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
118 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
119 field = 1 << MAIL_CUSTOM_FLAG_1_BIT; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
120 for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, field <<= 1) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
121 if ((ctx->msg_flags & field) && ctx->custom_flags[i] != NULL) { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
122 if (o_stream_send(ctx->output, " ", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
123 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
124 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
125 if (o_stream_send(ctx->output, ctx->custom_flags[i], |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
126 strlen(ctx->custom_flags[i])) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
127 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
128 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
129 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
130 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
131 if (x_keywords != NULL) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
132 /* X-Keywords that aren't custom flags */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
133 if (o_stream_send(ctx->output, " ", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
134 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
135 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
136 if (o_stream_send(ctx->output, x_keywords, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
137 strlen(x_keywords)) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
138 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
139 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
140 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
141 if (o_stream_send(ctx->output, "\n", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
142 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
143 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
144 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
145 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
146 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
147 static int mbox_write_status(MboxRewriteContext *ctx, const char *status) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
148 { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
149 const char *str; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
150 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
151 str = (ctx->msg_flags & MAIL_SEEN) ? "Status: RO" : "Status: O"; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
152 if (status != NULL) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
153 str = t_strconcat(str, status, NULL); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
154 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
155 if (o_stream_send(ctx->output, str, strlen(str)) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
156 return FALSE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
157 if (o_stream_send(ctx->output, "\n", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
158 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
159 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
160 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
161 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
162 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
163 static int mbox_write_xstatus(MboxRewriteContext *ctx, const char *x_status) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
164 { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
165 const char *str; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
166 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
167 /* X-Status field */ |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
168 if ((ctx->msg_flags & (MAIL_SYSTEM_FLAGS_MASK^MAIL_SEEN)) == 0 && |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
169 x_status == NULL) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
170 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
171 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
172 str = t_strconcat("X-Status: ", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
173 (ctx->msg_flags & MAIL_ANSWERED) ? "A" : "", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
174 (ctx->msg_flags & MAIL_DRAFT) ? "D" : "", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
175 (ctx->msg_flags & MAIL_FLAGGED) ? "F" : "", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
176 (ctx->msg_flags & MAIL_DELETED) ? "T" : "", |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
177 x_status, NULL); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
178 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
179 if (o_stream_send(ctx->output, str, strlen(str)) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
180 return FALSE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
181 if (o_stream_send(ctx->output, "\n", 1) < 0) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
182 return FALSE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
183 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
184 return TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
185 } |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
186 |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
187 static int mbox_write_content_length(MboxRewriteContext *ctx) |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
188 { |
678
1e5c655bad25
Renamed largest_t to uintmax_t which already exists in C99.
Timo Sirainen <tss@iki.fi>
parents:
642
diff
changeset
|
189 char str[MAX_INT_STRLEN+30]; |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
190 |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
191 i_snprintf(str, sizeof(str), "Content-Length: %"PRIuUOFF_T"\n", |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
192 ctx->content_length); |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
193 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
194 if (o_stream_send(ctx->output, str, strlen(str)) < 0) |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
195 return FALSE; |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
196 return TRUE; |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
197 } |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
198 |
184 | 199 static const char *strip_chars(const char *value, size_t value_len, |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 const char *list) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 /* leave only unknown flags, very likely none */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 char *ret, *p; |
765
553f050c8313
Added buffer API. Point is to hide all buffer writing behind this API which
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
204 size_t i; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 ret = p = t_buffer_get(value_len+1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 for (i = 0; i < value_len; i++) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 if (strchr(list, value[i]) == NULL) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 *p++ = value[i]; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
210 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
212 if (ret == p) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 return NULL; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 *p = '\0'; |
184 | 215 t_buffer_alloc((size_t) (p-ret)+1); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 return ret; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 |
184 | 219 static void update_stripped_custom_flags(const char *value, size_t len, |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
220 int index, void *context) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 TempString *str = context; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
224 if (index < 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
225 /* not found, keep it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
226 if (str->len != 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
227 t_string_append_c(str, ' '); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
228 t_string_append_n(str, value, len); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
229 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
231 |
184 | 232 static const char *strip_custom_flags(const char *value, size_t len, |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
233 MboxRewriteContext *ctx) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
234 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
235 TempString *str; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
236 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
237 str = t_string_new(len+1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 mbox_keywords_parse(value, len, ctx->custom_flags, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 update_stripped_custom_flags, str); |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
240 return str->len == 0 ? NULL : str->str; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
243 static void header_func(MessagePart *part __attr_unused__, |
184 | 244 const char *name, size_t name_len, |
245 const char *value, size_t value_len, | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 void *context) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 MboxRewriteContext *ctx = context; |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
249 const char *str; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
250 char *end; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
252 if (ctx->failed) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
253 return; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
254 |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
255 if (name_len == 6 && strncasecmp(name, "Status", 6) == 0) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
256 ctx->status_found = TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
257 str = strip_chars(value, value_len, "RO"); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
258 (void)mbox_write_status(ctx, str); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
259 } else if (name_len == 8 && strncasecmp(name, "X-Status", 8) == 0) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
260 ctx->xstatus_found = TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
261 str = strip_chars(value, value_len, "ADFT"); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
262 (void)mbox_write_xstatus(ctx, str); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
263 } else if (name_len == 10 && strncasecmp(name, "X-Keywords", 10) == 0) { |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
264 ctx->ximapbase_found = TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
265 str = strip_custom_flags(value, value_len, ctx); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
266 (void)mbox_write_xkeywords(ctx, str); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
267 } else if (name_len == 10 && strncasecmp(name, "X-IMAPbase", 10) == 0) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 if (ctx->seq == 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 /* temporarily copy the value to make sure we |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 don't overflow it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 t_push(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
272 value = t_strndup(value, value_len); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
273 ctx->uid_validity = strtoul(value, &end, 10); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 while (*end == ' ') end++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 ctx->uid_last = strtoul(end, &end, 10); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 t_pop(); |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
277 |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
278 ctx->ximapbase_found = TRUE; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
279 (void)mbox_write_ximapbase(ctx); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
280 } |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
281 } else if (name_len == 14 && |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
282 strncasecmp(name, "Content-Length", 14) == 0) { |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
283 ctx->content_length_found = TRUE; |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
284 (void)mbox_write_content_length(ctx); |
369
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
365
diff
changeset
|
285 } else if (name_len > 0) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 /* save this header */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
287 (void)o_stream_send(ctx->output, name, name_len); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
288 (void)o_stream_send(ctx->output, ": ", 2); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
289 (void)o_stream_send(ctx->output, value, value_len); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
290 (void)o_stream_send(ctx->output, "\n", 1); |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
291 } |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
293 if (ctx->output->closed) |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
294 ctx->failed = TRUE; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 static int mbox_write_header(MailIndex *index, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 MailIndexRecord *rec, unsigned int seq, |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
299 IStream *input, OStream *output, uoff_t end_offset, |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
300 uoff_t hdr_size, uoff_t body_size) |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 /* We need to update fields that define message flags. Standard fields |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 are stored in Status and X-Status. For custom flags we use |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 uw-imapd compatible format, by first listing them in first message's |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 X-IMAPbase field and actually defining them in X-Keywords field. |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 Format of X-IMAPbase is: <UID validity> <last used UID> <flag names> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 We don't want to sync our UIDs with the mbox file, so the UID |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 validity is always kept different from our internal UID validity. |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 Last used UID is also not updated, and set to 0 initially. |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 MboxRewriteContext ctx; |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
314 MessageSize hdr_parsed_size; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
316 if (input->v_offset >= end_offset) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 /* fsck should have noticed it.. */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 index_set_error(index, "Error rewriting mbox file %s: " |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
217
diff
changeset
|
319 "Unexpected end of file", index->mbox_path); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
323 t_push(); |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
324 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 /* parse the header, write the fields we don't want to change */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 memset(&ctx, 0, sizeof(ctx)); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
327 ctx.output = output; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 ctx.seq = seq; |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
329 ctx.content_length = body_size; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 ctx.msg_flags = rec->msg_flags; |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
331 ctx.uid_validity = index->header->uid_validity-1; |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
332 ctx.custom_flags = mail_custom_flags_list_get(index->custom_flags); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
334 i_stream_set_read_limit(input, input->v_offset + hdr_size); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
335 message_parse_header(NULL, input, &hdr_parsed_size, header_func, &ctx); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
336 i_stream_set_read_limit(input, 0); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
337 |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
338 i_assert(hdr_parsed_size.physical_size == hdr_size); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
339 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
340 /* append the flag fields */ |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
341 if (seq == 1 && !ctx.ximapbase_found) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 /* write X-IMAPbase header to first message */ |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
343 (void)mbox_write_ximapbase(&ctx); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 |
362
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
346 if (!ctx.xkeywords_found) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
347 (void)mbox_write_xkeywords(&ctx, NULL); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
348 if (!ctx.status_found) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
349 (void)mbox_write_status(&ctx, NULL); |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
350 if (!ctx.xstatus_found) |
aa449d013563
When updating any of the fields, keep them in the original location in
Timo Sirainen <tss@iki.fi>
parents:
312
diff
changeset
|
351 (void)mbox_write_xstatus(&ctx, NULL); |
370
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
352 if (!ctx.content_length_found) |
b0a62e264b22
Write Content-Length header for rewritten messages.
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
353 (void)mbox_write_content_length(&ctx); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 t_pop(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 /* empty line ends headers */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
358 (void)o_stream_send(output, "\n", 1); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
360 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
363 static int fd_copy(int in_fd, int out_fd, uoff_t out_offset) |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
364 { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
365 IStream *input; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
366 OStream *output; |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
367 int ret; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
368 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
369 i_assert(out_offset <= OFF_T_MAX); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
370 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
371 if (lseek(out_fd, (off_t)out_offset, SEEK_SET) < 0) |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
372 return -1; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
373 |
404
f25e575bf1ca
Created datastack_mempool which is used by at least a few temporary
Timo Sirainen <tss@iki.fi>
parents:
389
diff
changeset
|
374 t_push(); |
f25e575bf1ca
Created datastack_mempool which is used by at least a few temporary
Timo Sirainen <tss@iki.fi>
parents:
389
diff
changeset
|
375 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
376 input = i_stream_create_mmap(in_fd, data_stack_pool, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
377 1024*256, 0, 0, FALSE); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
378 output = o_stream_create_file(out_fd, data_stack_pool, 1024, 0, FALSE); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
379 o_stream_set_blocking(output, 60000, NULL, NULL); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
380 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
381 ret = o_stream_send_istream(output, input); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
382 if (ret < 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
383 errno = output->stream_errno; |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
384 else { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
385 /* we may have shrinked the file */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
386 i_assert(out_offset + input->v_size <= OFF_T_MAX); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
387 ret = ftruncate(out_fd, (off_t) (out_offset + input->v_size)); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
388 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
389 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
390 o_stream_unref(output); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
391 i_stream_unref(input); |
404
f25e575bf1ca
Created datastack_mempool which is used by at least a few temporary
Timo Sirainen <tss@iki.fi>
parents:
389
diff
changeset
|
392 t_pop(); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
393 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
394 return ret; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
395 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
396 |
629
2f3b2a5d74d7
If first message with our X-IMAPbase is deleted, make sure it's added back.
Timo Sirainen <tss@iki.fi>
parents:
604
diff
changeset
|
397 #define INDEX_DIRTY_FLAGS \ |
2f3b2a5d74d7
If first message with our X-IMAPbase is deleted, make sure it's added back.
Timo Sirainen <tss@iki.fi>
parents:
604
diff
changeset
|
398 (MAIL_INDEX_FLAG_DIRTY_MESSAGES | MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS) |
2f3b2a5d74d7
If first message with our X-IMAPbase is deleted, make sure it's added back.
Timo Sirainen <tss@iki.fi>
parents:
604
diff
changeset
|
399 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
400 int mbox_index_rewrite(MailIndex *index) |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
401 { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
402 /* Write messages beginning from the first dirty one to temp file, |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
403 then copy it over the mbox file. This may create data loss if |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
404 interrupted (see below). This rewriting relies quite a lot on |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
405 valid header/body sizes which fsck() should have ensured. */ |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
406 MailIndexRecord *rec; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
407 IStream *input; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
408 OStream *output; |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
409 uoff_t offset, hdr_size, body_size, dirty_offset; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
410 const char *path; |
194 | 411 unsigned int seq; |
521
83da62e0675a
mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents:
484
diff
changeset
|
412 int tmp_fd, failed, dirty_found, rewrite; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
413 |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
414 i_assert(index->lock_type == MAIL_LOCK_UNLOCK); |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
415 |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
416 if (!index->set_lock(index, MAIL_LOCK_SHARED)) |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
417 return FALSE; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
418 |
642
5f5fdc45c19d
Don't rewrite when there's no messages (ie. don't write the one '\n').
Timo Sirainen <tss@iki.fi>
parents:
629
diff
changeset
|
419 rewrite = (index->header->flags & INDEX_DIRTY_FLAGS) && |
5f5fdc45c19d
Don't rewrite when there's no messages (ie. don't write the one '\n').
Timo Sirainen <tss@iki.fi>
parents:
629
diff
changeset
|
420 index->header->messages_count > 0; |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
421 |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
422 if (!index->set_lock(index, MAIL_LOCK_UNLOCK)) |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
423 return FALSE; |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
424 |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
425 if (!rewrite) { |
303
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
426 /* no need to rewrite */ |
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
427 return TRUE; |
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
428 } |
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
429 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
430 tmp_fd = -1; input = NULL; |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
431 failed = TRUE; rewrite = FALSE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
432 do { |
570
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
433 if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
434 break; |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
435 |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
436 if (!index->sync_and_lock(index, MAIL_LOCK_EXCLUSIVE, NULL)) |
556 | 437 break; |
438 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
439 input = mbox_get_stream(index, 0, MAIL_LOCK_EXCLUSIVE); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
440 if (input == NULL) |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
441 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
442 |
629
2f3b2a5d74d7
If first message with our X-IMAPbase is deleted, make sure it's added back.
Timo Sirainen <tss@iki.fi>
parents:
604
diff
changeset
|
443 if ((index->header->flags & INDEX_DIRTY_FLAGS) == 0) { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
444 /* fsck() figured out there's no dirty messages |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
445 after all */ |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
446 failed = FALSE; rewrite = FALSE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
447 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
448 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
449 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
450 tmp_fd = mail_index_create_temp_file(index, &path); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
451 if (tmp_fd == -1) |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
452 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
453 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
454 failed = FALSE; rewrite = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
455 } while (0); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
456 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
457 if (!rewrite) { |
560 | 458 if (!index->set_lock(index, MAIL_LOCK_UNLOCK)) |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
459 failed = TRUE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
460 if (input != NULL) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
461 i_stream_unref(input); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
462 return !failed; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
463 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
464 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
465 if (index->header->flags & MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS) { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
466 /* need to update X-IMAPbase in first message */ |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
467 dirty_found = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
468 } else { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
469 dirty_found = FALSE; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
470 } |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
471 dirty_offset = 0; |
298
5509d87fe68b
mbox locking changes. support read-locking now. there's still problems
Timo Sirainen <tss@iki.fi>
parents:
297
diff
changeset
|
472 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
473 /* note: we can't use data_stack_pool with output stream because it's |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
474 being written to inside t_push() .. t_pop() calls */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
475 output = o_stream_create_file(tmp_fd, system_pool, 8192, 0, FALSE); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
476 o_stream_set_blocking(output, 60000, NULL, NULL); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
477 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
478 failed = FALSE; seq = 1; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
479 rec = index->lookup(index, 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
480 while (rec != NULL) { |
383 | 481 if (dirty_found || (rec->index_flags & INDEX_MAIL_FLAG_DIRTY)) { |
482 /* get offset to beginning of mail headers */ | |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
483 if (!mbox_mail_get_location(index, rec, &offset, |
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
484 &hdr_size, &body_size)) { |
383 | 485 /* fsck should have fixed it */ |
486 failed = TRUE; | |
487 break; | |
488 } | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
489 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
490 if (offset < input->v_offset) { |
570
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
491 index_set_corrupted(index, |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
492 "Invalid message offset"); |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
493 failed = TRUE; |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
494 break; |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
495 } |
2626acd3c6f4
And more locking/syncing fixes. Now it's finally beginning to look sane
Timo Sirainen <tss@iki.fi>
parents:
560
diff
changeset
|
496 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
497 if (offset + hdr_size + body_size > input->v_size) { |
383 | 498 index_set_corrupted(index, |
499 "Invalid message size"); | |
500 failed = TRUE; | |
501 break; | |
502 } | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
504 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
505 if (!dirty_found && |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
506 (rec->index_flags & INDEX_MAIL_FLAG_DIRTY)) { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
507 /* first dirty message */ |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
508 dirty_found = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
509 dirty_offset = offset; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
510 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
511 i_stream_seek(input, dirty_offset); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
512 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
513 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
514 if (dirty_found) { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
515 /* write the From-line */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
516 if (!mbox_write(index, input, output, offset)) { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
517 failed = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
518 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
519 } |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
520 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
521 /* write header, updating flag fields */ |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
522 offset += hdr_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
523 if (!mbox_write_header(index, rec, seq, input, output, |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
524 offset, hdr_size, body_size)) { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
525 failed = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
526 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
527 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
528 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
529 /* write body */ |
525
2cb2e0a3423b
Moved several fields from .imap.index file to .imap.index.data file. Fixed
Timo Sirainen <tss@iki.fi>
parents:
521
diff
changeset
|
530 offset += body_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
531 if (!mbox_write(index, input, output, offset)) { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
532 failed = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
533 break; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
534 } |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
535 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
536 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
537 seq++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
538 rec = index->next(index, rec); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
539 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
540 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
541 if (!dirty_found) { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
542 index_set_error(index, "Expected dirty messages not found " |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
543 "from mbox file %s", index->mbox_path); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
544 failed = TRUE; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
545 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
546 |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
547 if (!failed) { |
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
548 /* always end with a \n */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
549 (void)o_stream_send(output, "\n", 1); |
484
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
550 } |
006202bcab99
input buffer limit wasn't reset in error conditions.
Timo Sirainen <tss@iki.fi>
parents:
452
diff
changeset
|
551 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
552 if (output->closed) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
553 errno = output->stream_errno; |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
217
diff
changeset
|
554 mbox_set_syscall_error(index, "write()"); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
555 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
556 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
557 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
558 i_stream_unref(input); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
678
diff
changeset
|
559 o_stream_unref(output); |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
560 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
561 if (!failed) { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
562 /* POSSIBLE DATA LOSS HERE. We're writing to the mbox file, |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
563 so if we get killed here before finished, we'll lose some |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
564 bytes. I can't really think of any way to fix this, |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
565 rename() is problematic too especially because of file |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
566 locking issues (new mail could be lost). |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
567 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
568 Usually we're moving the data by just a few bytes, so |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
569 the data loss should never be more than those few bytes.. |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
570 If we moved more, we could have written the file from end |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
571 to beginning in blocks (it'd be a bit slow to do it in |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
572 blocks of ~1-10 bytes which is the usual case, so we don't |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
573 bother). |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
574 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
575 Also, we might as well be shrinking the file, in which |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
576 case we can't lose data. */ |
364
ea958a5b9de1
Added io_buffer_set_start_offset() and io_buffer_ref() and replaced
Timo Sirainen <tss@iki.fi>
parents:
363
diff
changeset
|
577 if (fd_copy(tmp_fd, index->mbox_fd, dirty_offset) == 0) { |
269
a4eb58705351
FSCK flag is removed at set_lock(), so it can't be directly set anywhere..
Timo Sirainen <tss@iki.fi>
parents:
241
diff
changeset
|
578 /* all ok, we need to fsck the index next time. |
a4eb58705351
FSCK flag is removed at set_lock(), so it can't be directly set anywhere..
Timo Sirainen <tss@iki.fi>
parents:
241
diff
changeset
|
579 use set_flags because set_lock() would remove it |
a4eb58705351
FSCK flag is removed at set_lock(), so it can't be directly set anywhere..
Timo Sirainen <tss@iki.fi>
parents:
241
diff
changeset
|
580 if we modified it directly */ |
a4eb58705351
FSCK flag is removed at set_lock(), so it can't be directly set anywhere..
Timo Sirainen <tss@iki.fi>
parents:
241
diff
changeset
|
581 index->set_flags |= MAIL_INDEX_FLAG_FSCK; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
582 reset_dirty_flags(index); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
583 } else { |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
584 mbox_set_syscall_error(index, "fd_copy()"); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
585 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
586 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
587 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
588 |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
589 if (!index->set_lock(index, MAIL_LOCK_UNLOCK)) |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
590 failed = TRUE; |
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
591 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
592 (void)unlink(path); |
297
ef6ae9e1b585
some cleanups + fd leaks when recaching mailbox.
Timo Sirainen <tss@iki.fi>
parents:
290
diff
changeset
|
593 |
312
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
594 if (close(tmp_fd) < 0) |
297
ef6ae9e1b585
some cleanups + fd leaks when recaching mailbox.
Timo Sirainen <tss@iki.fi>
parents:
290
diff
changeset
|
595 index_file_set_syscall_error(index, path, "close()"); |
559
c834e77b624c
Mostly mbox locking/syncing fixes. Still some problems though.
Timo Sirainen <tss@iki.fi>
parents:
556
diff
changeset
|
596 return !failed; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
597 } |