Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-index/mbox/mbox-rewrite.c @ 312:f5e59d65d124 HEAD
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
play nicely now with symlinks and avoid possible data loss when new mail was
being sent while we were rewriting.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 24 Sep 2002 19:39:00 +0300 |
parents | 19108e7c5af2 |
children | aa449d013563 |
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" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "iobuffer.h" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "temp-string.h" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "write-full.h" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #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
|
8 #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
|
9 #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
|
10 #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
|
11 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #include <stdio.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include <stdlib.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include <unistd.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 #include <fcntl.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 typedef struct { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 IOBuffer *outbuf; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 int failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 unsigned int seq; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 unsigned int msg_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 const char **custom_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 const char *status, *x_status, *x_keywords; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 unsigned int uid_validity; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 unsigned int uid_last; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 } MboxRewriteContext; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 /* 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
|
31 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
|
32 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 MailIndexRecord *rec; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 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
|
36 while (rec != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 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
|
38 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
|
39 } |
209
d85a6898bf39
Don't rewrite mbox if no flags were changed.
Timo Sirainen <tss@iki.fi>
parents:
194
diff
changeset
|
40 |
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
|
41 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
|
42 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
|
43 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 static int mbox_write(MailIndex *index, IOBuffer *inbuf, IOBuffer *outbuf, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 uoff_t end_offset) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 i_assert(inbuf->offset <= end_offset); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 if (io_buffer_send_iobuffer(outbuf, inbuf, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 end_offset - inbuf->offset) < 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 if (inbuf->offset < end_offset) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 /* 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
|
56 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
|
57 "Unexpected end of file", index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 |
184 | 64 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
|
65 const char *list) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 /* 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
|
68 char *ret, *p; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 unsigned int i; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 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
|
72 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
|
73 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
|
74 *p++ = value[i]; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 if (ret == p) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 return NULL; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 *p = '\0'; |
184 | 80 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
|
81 return ret; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 |
184 | 84 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
|
85 int index, void *context) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 TempString *str = context; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 if (index < 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 /* not found, keep it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 if (str->len != 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 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
|
93 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
|
94 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 |
184 | 97 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
|
98 MboxRewriteContext *ctx) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 TempString *str; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 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
|
103 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
|
104 update_stripped_custom_flags, str); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 return str->str; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 static void header_func(MessagePart *part __attr_unused__, |
184 | 109 const char *name, size_t name_len, |
110 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
|
111 void *context) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 MboxRewriteContext *ctx = context; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 char *end; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 if (ctx->failed) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 return; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 if (name_len == 6 && strncasecmp(name, "Status", 6) == 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 ctx->status = strip_chars(value, value_len, "RO"); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 else if (name_len == 8 && strncasecmp(name, "X-Status", 8) == 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 ctx->x_status = strip_chars(value, value_len, "ADFT"); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 else if (name_len == 10 && strncasecmp(name, "X-Keywords", 10) == 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 ctx->x_keywords = strip_custom_flags(value, value_len, ctx); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 else if (name_len == 10 && strncasecmp(name, "X-IMAPbase", 10) == 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 if (ctx->seq == 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 /* 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
|
128 don't overflow it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 t_push(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 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
|
131 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
|
132 while (*end == ' ') end++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 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
|
134 t_pop(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
135 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 } else { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 /* save this header */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 (void)io_buffer_send(ctx->outbuf, name, name_len); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 (void)io_buffer_send(ctx->outbuf, ": ", 2); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 (void)io_buffer_send(ctx->outbuf, value, value_len); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 (void)io_buffer_send(ctx->outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 if (ctx->outbuf->closed) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 ctx->failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 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
|
149 MailIndexRecord *rec, unsigned int seq, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 IOBuffer *inbuf, IOBuffer *outbuf, |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
151 uoff_t end_offset) |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 /* 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
|
154 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
|
155 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
|
156 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
|
157 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 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
|
159 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 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
|
161 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
|
162 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
|
163 */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 MboxRewriteContext ctx; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 MessageSize hdr_size; |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
166 const char *str, *flags, **custom_flags; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 unsigned int field; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 int i; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 if (inbuf->offset >= end_offset) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 /* 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
|
172 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
|
173 "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
|
174 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
175 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
176 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
177 t_push(); |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
178 |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
179 custom_flags = mail_custom_flags_list_get(index->custom_flags); |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
180 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 /* 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
|
182 memset(&ctx, 0, sizeof(ctx)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 ctx.outbuf = outbuf; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 ctx.seq = seq; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 ctx.msg_flags = rec->msg_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 ctx.custom_flags = custom_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 |
290
3dcc2275b4ca
IOBuffer cleanup, hopefully fixes some mbox problems.
Timo Sirainen <tss@iki.fi>
parents:
269
diff
changeset
|
188 io_buffer_set_read_limit(inbuf, inbuf->offset + rec->header_size); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 message_parse_header(NULL, inbuf, &hdr_size, header_func, &ctx); |
290
3dcc2275b4ca
IOBuffer cleanup, hopefully fixes some mbox problems.
Timo Sirainen <tss@iki.fi>
parents:
269
diff
changeset
|
190 io_buffer_set_read_limit(inbuf, 0); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 i_assert(hdr_size.physical_size == rec->header_size); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
193 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
194 /* append the flag fields */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
195 if (seq == 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
196 /* write X-IMAPbase header to first message */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
197 if (ctx.uid_validity == 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
198 ctx.uid_validity = index->header->uid_validity-1; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 str = t_strdup_printf("X-IMAPbase: %u %u", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 ctx.uid_validity, ctx.uid_last); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 (void)io_buffer_send(outbuf, str, strlen(str)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 if (custom_flags[i] != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 (void)io_buffer_send(outbuf, " ", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 (void)io_buffer_send(outbuf, custom_flags[i], |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 strlen(custom_flags[i])); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 } |
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 (void)io_buffer_send(outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
212 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 if ((rec->msg_flags & MAIL_CUSTOM_FLAGS_MASK) || |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
215 ctx.x_keywords != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 /* write X-Keywords header containing custom flags */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 (void)io_buffer_send(outbuf, "X-Keywords:", 11); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
219 field = 1 << MAIL_CUSTOM_FLAG_1_BIT; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
220 for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, field <<= 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 if ((rec->msg_flags & field) && |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 custom_flags[i] != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 (void)io_buffer_send(outbuf, " ", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
224 (void)io_buffer_send(outbuf, custom_flags[i], |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
225 strlen(custom_flags[i])); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
226 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
227 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
228 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
229 if (ctx.x_keywords != NULL && ctx.x_keywords[0] != '\0') { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 /* X-Keywords that aren't custom flags */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
231 (void)io_buffer_send(outbuf, " ", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
232 (void)io_buffer_send(outbuf, ctx.x_keywords, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
233 strlen(ctx.x_keywords)); |
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 (void)io_buffer_send(outbuf, "\n", 1); |
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 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 /* Status field */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 flags = (rec->msg_flags & MAIL_SEEN) ? "Status: RO" : "Status: O"; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 flags = t_strconcat(flags, ctx.status, NULL); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 (void)io_buffer_send(outbuf, flags, strlen(flags)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 (void)io_buffer_send(outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
243 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
244 /* X-Status field */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
245 if ((rec->msg_flags & (MAIL_SYSTEM_FLAGS_MASK^MAIL_SEEN)) != 0 || |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 ctx.x_status != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 flags = t_strconcat("X-Status: ", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 (rec->msg_flags & MAIL_ANSWERED) ? "A" : "", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 (rec->msg_flags & MAIL_DRAFT) ? "D" : "", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
250 (rec->msg_flags & MAIL_FLAGGED) ? "F" : "", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 (rec->msg_flags & MAIL_DELETED) ? "T" : "", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
252 ctx.x_status, NULL); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
253 (void)io_buffer_send(outbuf, flags, strlen(flags)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
254 (void)io_buffer_send(outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
255 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
256 t_pop(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
257 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
258 mail_custom_flags_list_unref(index->custom_flags); |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
259 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 /* empty line ends headers */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
261 (void)io_buffer_send(outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
263 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
264 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
265 |
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
|
266 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
|
267 { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
268 IOBuffer *inbuf, *outbuf; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
269 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
|
270 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
271 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
|
272 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
273 if (lseek(in_fd, 0, 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
|
274 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
|
275 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
|
276 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
|
277 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
278 inbuf = io_buffer_create_mmap(in_fd, default_pool, 65536, 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
|
279 outbuf = io_buffer_create_file(out_fd, default_pool, 1024); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
280 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
281 ret = io_buffer_send_iobuffer(outbuf, inbuf, inbuf->size); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
282 if (ret < 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
|
283 errno = outbuf->buf_errno; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
284 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
|
285 /* we may have shrinked the 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
|
286 i_assert(out_offset + inbuf->size <= 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
|
287 ret = ftruncate(out_fd, (off_t) (out_offset + inbuf->size)); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
288 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
289 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
290 io_buffer_destroy(outbuf); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
291 io_buffer_destroy(inbuf); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
292 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
293 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
|
294 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
295 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
296 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
|
297 { |
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
|
298 /* 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
|
299 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
|
300 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
|
301 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
|
302 MailIndexRecord *rec; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 IOBuffer *inbuf, *outbuf; |
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
|
304 uoff_t offset, dirty_offset; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 const char *path; |
194 | 306 unsigned int seq; |
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
|
307 int mbox_fd, tmp_fd, failed, dirty_found, locked, rewrite; |
160
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 i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 |
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
|
311 if ((index->header->flags & MAIL_INDEX_FLAG_DIRTY_MESSAGES) == 0) { |
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
312 /* 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
|
313 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
|
314 } |
19108e7c5af2
Actually, first don't do anything if there's no dirty flags. Then fsck().
Timo Sirainen <tss@iki.fi>
parents:
301
diff
changeset
|
315 |
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
|
316 mbox_fd = tmp_fd = -1; locked = 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
|
317 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
|
318 do { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
319 /* lock before fscking to prevent race conditions between |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
320 fsck's unlock and our lock. */ |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
321 mbox_fd = open(index->mbox_path, O_RDWR); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
322 if (mbox_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
|
323 mbox_set_syscall_error(index, "open()"); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
324 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
|
325 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
326 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
327 if (!mbox_lock(index, index->mbox_path, mbox_fd, 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
|
328 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
|
329 locked = 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
|
330 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
331 if (!mbox_index_fsck(index)) |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
332 break; |
301
1d4d92c2e8c9
fsck() before checking the rewrite-flag, so we won't write the 1-byte
Timo Sirainen <tss@iki.fi>
parents:
300
diff
changeset
|
333 |
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
|
334 if ((index->header->flags & |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
335 MAIL_INDEX_FLAG_DIRTY_MESSAGES) == 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
|
336 /* 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
|
337 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
|
338 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
|
339 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
|
340 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
341 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
342 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
|
343 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
|
344 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
|
345 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
346 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
|
347 } 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
|
348 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
349 if (!rewrite) { |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
350 if (locked) |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
351 (void)mbox_unlock(index, index->mbox_path, mbox_fd); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
352 if (mbox_fd != -1 && close(mbox_fd) < 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
|
353 mbox_set_syscall_error(index, "close()"); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
354 return !failed; |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 |
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
|
357 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
|
358 /* 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
|
359 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
|
360 } 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
|
361 dirty_found = FALSE; |
160
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 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
|
364 |
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
|
365 inbuf = io_buffer_create_mmap(mbox_fd, default_pool, |
298
5509d87fe68b
mbox locking changes. support read-locking now. there's still problems
Timo Sirainen <tss@iki.fi>
parents:
297
diff
changeset
|
366 MAIL_MMAP_BLOCK_SIZE, 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
|
367 outbuf = io_buffer_create_file(tmp_fd, default_pool, 8192); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 failed = FALSE; seq = 1; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 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
|
371 while (rec != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 /* get offset to beginning of mail headers */ |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
217
diff
changeset
|
373 if (!mbox_mail_get_start_offset(index, rec, &offset)) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 /* fsck should have fixed it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
375 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
377 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
378 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
379 if (offset + rec->header_size + rec->body_size > inbuf->size) { |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
217
diff
changeset
|
380 index_set_corrupted(index, "Invalid message size"); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
381 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
382 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
383 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
384 |
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
|
385 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
|
386 (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
|
387 /* 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
|
388 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
|
389 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
|
390 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
391 io_buffer_seek(inbuf, dirty_offset); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
392 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
393 |
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
|
394 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
|
395 /* write the From-line */ |
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 if (!mbox_write(index, inbuf, outbuf, 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
|
397 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
|
398 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
|
399 } |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
400 |
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
|
401 /* write header, updating flag fields */ |
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 offset += rec->header_size; |
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 if (!mbox_write_header(index, rec, seq, inbuf, outbuf, |
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 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
|
405 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
|
406 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
|
407 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
408 |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
409 /* write body */ |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
410 offset += rec->body_size; |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
411 if (!mbox_write(index, inbuf, outbuf, 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
|
412 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
|
413 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
|
414 } |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
415 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
416 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
417 seq++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
418 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
|
419 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
420 |
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
|
421 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
|
422 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
|
423 "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
|
424 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
|
425 } |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
426 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
427 /* always end with a \n */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
428 (void)io_buffer_send(outbuf, "\n", 1); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
429 if (outbuf->closed) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
430 errno = outbuf->buf_errno; |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
217
diff
changeset
|
431 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
|
432 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
433 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
434 |
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
|
435 io_buffer_destroy(outbuf); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
436 io_buffer_destroy(inbuf); |
f5e59d65d124
Rewrite only needed parts of mbox. We don't rename() anymore, which means we
Timo Sirainen <tss@iki.fi>
parents:
303
diff
changeset
|
437 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
438 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
|
439 /* 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
|
440 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
|
441 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
|
442 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
|
443 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
|
444 |
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 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
|
446 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
|
447 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
|
448 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
|
449 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
|
450 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
|
451 |
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 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
|
453 case we can't lose data. */ |
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 if (fd_copy(tmp_fd, 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
|
455 /* 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
|
456 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
|
457 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
|
458 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
|
459 reset_dirty_flags(index); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
460 } 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
|
461 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
|
462 failed = TRUE; |
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 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
465 |
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
|
466 (void)mbox_unlock(index, index->mbox_path, mbox_fd); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
467 (void)unlink(path); |
297
ef6ae9e1b585
some cleanups + fd leaks when recaching mailbox.
Timo Sirainen <tss@iki.fi>
parents:
290
diff
changeset
|
468 |
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
|
469 if (close(mbox_fd) < 0) |
298
5509d87fe68b
mbox locking changes. support read-locking now. there's still problems
Timo Sirainen <tss@iki.fi>
parents:
297
diff
changeset
|
470 mbox_set_syscall_error(index, "close()"); |
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 if (close(tmp_fd) < 0) |
297
ef6ae9e1b585
some cleanups + fd leaks when recaching mailbox.
Timo Sirainen <tss@iki.fi>
parents:
290
diff
changeset
|
472 index_file_set_syscall_error(index, path, "close()"); |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
473 return failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
474 } |