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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
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
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
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
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
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
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
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
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
109 const char *name, size_t name_len,
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 180
diff changeset
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
d82e7d23a28d more size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
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 }