Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-index/mbox/mbox-rewrite.c @ 194:d82e7d23a28d HEAD
more size_t fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 08 Sep 2002 18:22:45 +0300 |
parents | 4223b9ed0c80 |
children | d85a6898bf39 |
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" |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #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
|
9 #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
|
10 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #include <stdio.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #include <stdlib.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include <unistd.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include <fcntl.h> |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 typedef struct { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 IOBuffer *outbuf; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 int failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 unsigned int seq; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 unsigned int msg_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 const char **custom_flags; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 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
|
25 unsigned int uid_validity; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 unsigned int uid_last; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 } MboxRewriteContext; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 /* 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
|
30 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
|
31 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 MailIndexRecord *rec; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 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
|
35 while (rec != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 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
|
37 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
|
38 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 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
|
42 uoff_t end_offset) |
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 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
|
45 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 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
|
47 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
|
48 return FALSE; |
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 (inbuf->offset < end_offset) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 /* 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
|
52 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
|
53 "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
|
54 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 |
184 | 60 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
|
61 const char *list) |
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 /* 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
|
64 char *ret, *p; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 unsigned int i; |
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 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
|
68 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
|
69 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
|
70 *p++ = value[i]; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 if (ret == p) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 return NULL; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 *p = '\0'; |
184 | 76 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
|
77 return ret; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 |
184 | 80 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
|
81 int index, void *context) |
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 TempString *str = context; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 if (index < 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 /* not found, keep it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 if (str->len != 0) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 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
|
89 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
|
90 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 |
184 | 93 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
|
94 MboxRewriteContext *ctx) |
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 TempString *str; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 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
|
99 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
|
100 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
|
101 return str->str; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 static void header_func(MessagePart *part __attr_unused__, |
184 | 105 const char *name, size_t name_len, |
106 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
|
107 void *context) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 MboxRewriteContext *ctx = context; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 char *end; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 if (ctx->failed) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 return; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 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
|
116 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
|
117 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
|
118 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
|
119 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
|
120 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
|
121 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
|
122 if (ctx->seq == 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 /* 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
|
124 don't overflow it */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 t_push(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 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
|
127 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
|
128 while (*end == ' ') end++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 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
|
130 t_pop(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 } else { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 /* save this header */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 (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
|
135 (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
|
136 (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
|
137 (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
|
138 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 if (ctx->outbuf->closed) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 ctx->failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 } |
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 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 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
|
145 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
|
146 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
|
147 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
|
148 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 /* 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
|
150 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
|
151 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
|
152 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
|
153 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 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
|
155 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 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
|
157 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
|
158 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
|
159 */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 MboxRewriteContext ctx; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 MessageSize hdr_size; |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
162 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
|
163 unsigned int field; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 int i; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 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
|
167 /* 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
|
168 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
|
169 "Unexpected end of file", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
173 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
174 t_push(); |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
175 |
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
176 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
|
177 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
178 /* 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
|
179 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
|
180 ctx.outbuf = outbuf; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 ctx.seq = seq; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 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
|
183 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
|
184 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 message_parse_header(NULL, inbuf, &hdr_size, header_func, &ctx); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 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
|
188 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 /* append the flag fields */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 if (seq == 1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 /* 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
|
192 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
|
193 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
|
194 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
195 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
|
196 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
|
197 (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
|
198 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 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
|
200 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
|
201 (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
|
202 (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
|
203 strlen(custom_flags[i])); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 (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
|
207 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 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
|
210 ctx.x_keywords != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 /* 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
|
212 (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
|
213 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 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
|
215 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
|
216 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
|
217 custom_flags[i] != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 (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
|
219 (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
|
220 strlen(custom_flags[i])); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
224 if (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
|
225 /* 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
|
226 (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
|
227 (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
|
228 strlen(ctx.x_keywords)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
229 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 (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
|
231 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
232 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
233 /* Status field */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
234 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
|
235 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
|
236 (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
|
237 (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
|
238 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 /* X-Status field */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 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
|
241 ctx.x_status != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 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
|
243 (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
|
244 (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
|
245 (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
|
246 (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
|
247 ctx.x_status, NULL); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 (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
|
249 (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
|
250 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 t_pop(); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
252 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
253 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
|
254 |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
255 /* empty line ends headers */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
256 (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
|
257 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
258 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
259 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
261 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
|
262 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
263 /* Write it to temp file and then rename() to real file. |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
264 easier and much safer than moving data inside the file. |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
265 This rewriting relies quite a lot on valid header/body sizes |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
266 which fsck() should have ensured. */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 MailIndexRecord *rec; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 IOBuffer *inbuf, *outbuf; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 uoff_t offset; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 const uoff_t *location; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 const char *path; |
194 | 272 unsigned int seq; |
273 size_t size; | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 int in_fd, out_fd, failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 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
|
277 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
278 if (!mbox_index_fsck(index)) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
279 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
280 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 if (index->header->messages_count == 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 /* no messages in mailbox, don't bother rewriting */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 return TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 in_fd = open(index->mbox_path, O_RDWR); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
287 if (in_fd == -1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 index_set_error(index, "Can't open mbox file %s: %m", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
289 index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 inbuf = io_buffer_create_mmap(in_fd, default_pool, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 MAIL_MMAP_BLOCK_SIZE, 0); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 out_fd = mail_index_create_temp_file(index, &path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 if (out_fd == -1) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 (void)close(in_fd); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 return FALSE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 outbuf = io_buffer_create_file(out_fd, default_pool, 8192); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 failed = FALSE; seq = 1; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 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
|
304 while (rec != NULL) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 /* get offset to beginning of mail headers */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 location = index->lookup_field_raw(index, rec, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 FIELD_TYPE_LOCATION, &size); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 if (size != sizeof(uoff_t) || *location <= inbuf->offset) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 /* 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
|
310 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
|
311 "Invalid location field in index", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 offset = *location; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 if (offset + rec->header_size + rec->body_size > inbuf->size) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 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
|
320 "Invalid message size in index", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
324 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 /* write the From-line */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 if (!mbox_write(index, inbuf, outbuf, offset)) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
332 /* write header, updating flag fields */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 offset += rec->header_size; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 if (!mbox_write_header(index, rec, seq, inbuf, outbuf, |
180
38341ad6a9db
partial changes to add X-IMAPbase parser update custom flags
Timo Sirainen <tss@iki.fi>
parents:
160
diff
changeset
|
335 offset)) { |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
337 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
338 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
339 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
340 /* write body */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
341 offset += rec->body_size; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 if (!mbox_write(index, inbuf, outbuf, offset)) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
343 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 break; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
346 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
347 seq++; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
348 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
|
349 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
350 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
351 /* 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
|
352 (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
|
353 if (outbuf->closed) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 errno = outbuf->buf_errno; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 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
|
356 "write() failed: %m", index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
358 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
360 if (!failed) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 if (rename(path, index->mbox_path) == 0) { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 /* all ok, we need to fsck the index next time */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
363 index->header->flags |= MAIL_INDEX_FLAG_FSCK; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
364 reset_dirty_flags(index); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
365 } else { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
366 index_set_error(index, "rename(%s, %s) failed: %m", |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 path, index->mbox_path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 failed = TRUE; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
371 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 (void)close(out_fd); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
373 (void)close(in_fd); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 (void)unlink(path); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
375 io_buffer_destroy(outbuf); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 io_buffer_destroy(inbuf); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
377 return failed; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
378 } |