annotate src/lib-storage/index/mbox/mbox-save.c @ 9002:9d0037a997f4 HEAD

Initial commit for config rewrite.
author Timo Sirainen <tss@iki.fi>
date Tue, 27 Jan 2009 18:21:53 -0500
parents a9dd29e7dc4f
children 21d4363a3cf7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 8527
diff changeset
1 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
4 #include "ioloop.h"
3470
346a494c2feb Moved array declaration to array-decl.h and include it in lib.h. So array.h
Timo Sirainen <tss@iki.fi>
parents: 3464
diff changeset
5 #include "array.h"
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
6 #include "base64.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "hostpid.h"
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
8 #include "randgen.h"
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
9 #include "istream.h"
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 674
diff changeset
10 #include "ostream.h"
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
11 #include "str.h"
29
e9375147c0cb Added write_full() which is a simple wrapper around write() meant for
Timo Sirainen <tss@iki.fi>
parents: 22
diff changeset
12 #include "write-full.h"
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
13 #include "istream-header-filter.h"
6528
aedda93baa2c Use crlf input streams instead of output streams so message parser doesn't
Timo Sirainen <tss@iki.fi>
parents: 6511
diff changeset
14 #include "istream-crlf.h"
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
15 #include "istream-concat.h"
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
16 #include "message-parser.h"
3464
0661239a7034 Cache mail headers when saving mails to mbox. We should cache everything,
Timo Sirainen <tss@iki.fi>
parents: 3348
diff changeset
17 #include "index-mail.h"
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
18 #include "mbox-storage.h"
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
19 #include "mbox-file.h"
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
20 #include "mbox-from.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 #include "mbox-lock.h"
2973
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
22 #include "mbox-md5.h"
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
23 #include "mbox-sync-private.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
25 #include <stddef.h>
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 #include <stdlib.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 #include <unistd.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 #include <fcntl.h>
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
29 #include <sys/stat.h>
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
30 #include <utime.h>
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
31
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
32 #define MBOX_DELIVERY_ID_RAND_BYTES (64/8)
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
33
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
34 struct mbox_save_context {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
35 struct mail_save_context ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
36
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
37 struct mbox_mailbox *mbox;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
38 struct mail_index_transaction *trans;
3464
0661239a7034 Cache mail headers when saving mails to mbox. We should cache everything,
Timo Sirainen <tss@iki.fi>
parents: 3348
diff changeset
39 struct mail *mail;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
40 uoff_t append_offset, mail_offset;
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
41 time_t orig_atime;
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
42
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
43 string_t *headers;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
44 size_t space_end_idx;
5592
29ac17ec78ff Crashfix when saving mails
Timo Sirainen <tss@iki.fi>
parents: 5581
diff changeset
45 uint32_t seq, next_uid, uid_validity, first_saved_uid;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
46
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
47 struct istream *input;
6528
aedda93baa2c Use crlf input streams instead of output streams so message parser doesn't
Timo Sirainen <tss@iki.fi>
parents: 6511
diff changeset
48 struct ostream *output;
6339
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
49 uoff_t extra_hdr_offset, eoh_offset;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
50 char last_char;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
51
2973
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
52 struct mbox_md5_context *mbox_md5_ctx;
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
53 char *x_delivery_id_header;
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
54
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
55 unsigned int synced:1;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
56 unsigned int failed:1;
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
57 unsigned int finished:1;
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
58 };
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
59
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
60 static int write_error(struct mbox_save_context *ctx)
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
61 {
5613
f717fb4b31c0 Error handling rewrite.
Timo Sirainen <tss@iki.fi>
parents: 5592
diff changeset
62 mbox_set_syscall_error(ctx->mbox, "write()");
3348
34dea04a191e Crashfix for some failure handling.
Timo Sirainen <tss@iki.fi>
parents: 3322
diff changeset
63 ctx->failed = TRUE;
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
64 return -1;
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
65 }
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
66
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
67 static int mbox_seek_to_end(struct mbox_save_context *ctx, uoff_t *offset)
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
68 {
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
69 struct stat st;
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
70 char ch;
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
71 int fd;
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
72
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
73 if (ctx->mbox->mbox_writeonly) {
2986
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
74 *offset = 0;
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
75 return 0;
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
76 }
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
77
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
78 fd = ctx->mbox->mbox_fd;
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
79 if (fstat(fd, &st) < 0)
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
80 return mbox_set_syscall_error(ctx->mbox, "fstat()");
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
81
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
82 ctx->orig_atime = st.st_atime;
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
83
1039
793f05a7e50e signed/unsigned/const pointer fixes
Timo Sirainen <tss@iki.fi>
parents: 1030
diff changeset
84 *offset = (uoff_t)st.st_size;
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
85 if (st.st_size == 0)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
86 return 0;
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
87
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
88 if (lseek(fd, st.st_size-1, SEEK_SET) < 0)
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
89 return mbox_set_syscall_error(ctx->mbox, "lseek()");
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
90
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
91 if (read(fd, &ch, 1) != 1)
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
92 return mbox_set_syscall_error(ctx->mbox, "read()");
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
93
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
94 if (ch != '\n') {
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
95 if (write_full(fd, "\n", 1) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
96 return write_error(ctx);
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
97 *offset += 1;
521
83da62e0675a mbox locking fixes / changes. we now read-lock the mbox file before syncing
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
98 }
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
99
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
100 return 0;
223
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
101 }
ca6967899c05 More cleanups. lib-storage should handle "out of disk space" conditions
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
102
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
103 static int mbox_append_lf(struct mbox_save_context *ctx)
266
757c32a1920d expunging last message from mbox duplicated the whole file. appending mail
Timo Sirainen <tss@iki.fi>
parents: 223
diff changeset
104 {
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
105 if (o_stream_send(ctx->output, "\n", 1) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
106 return write_error(ctx);
266
757c32a1920d expunging last message from mbox duplicated the whole file. appending mail
Timo Sirainen <tss@iki.fi>
parents: 223
diff changeset
107
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
108 return 0;
266
757c32a1920d expunging last message from mbox duplicated the whole file. appending mail
Timo Sirainen <tss@iki.fi>
parents: 223
diff changeset
109 }
757c32a1920d expunging last message from mbox duplicated the whole file. appending mail
Timo Sirainen <tss@iki.fi>
parents: 223
diff changeset
110
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
111 static int write_from_line(struct mbox_save_context *ctx, time_t received_date,
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
112 const char *from_envelope)
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
113 {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
114 int ret;
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
115
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
116 T_BEGIN {
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
117 const char *line;
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
118
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
119 if (from_envelope == NULL) {
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 8077
diff changeset
120 struct mail_storage *storage =
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 8077
diff changeset
121 &ctx->mbox->storage->storage;
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 8077
diff changeset
122
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 8077
diff changeset
123 from_envelope = t_strconcat(storage->ns->user->username,
8596
2609eca99495 Added my_hostdomain() function which mbox code now uses instead of doing that internally.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
124 "@", my_hostdomain(), NULL);
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
125 }
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
126
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
127 /* save in local timezone, no matter what it was given with */
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
128 line = mbox_from_create(from_envelope, received_date);
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
129
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
130 if ((ret = o_stream_send_str(ctx->output, line)) < 0)
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
131 write_error(ctx);
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
132 } T_END;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
133 return ret;
314
d2a305fa0ec2 mbox ignored message flags for APPEND.
Timo Sirainen <tss@iki.fi>
parents: 305
diff changeset
134 }
d2a305fa0ec2 mbox ignored message flags for APPEND.
Timo Sirainen <tss@iki.fi>
parents: 305
diff changeset
135
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
136 static int mbox_write_content_length(struct mbox_save_context *ctx)
314
d2a305fa0ec2 mbox ignored message flags for APPEND.
Timo Sirainen <tss@iki.fi>
parents: 305
diff changeset
137 {
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
138 uoff_t end_offset;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
139 const char *str;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
140 size_t len;
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
141
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
142 if (ctx->mbox->mbox_writeonly) {
2986
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
143 /* we can't seek, don't set Content-Length */
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
144 return 0;
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
145 }
51a05fd00324 Named pipes are now treated as write-only mboxes.
Timo Sirainen <tss@iki.fi>
parents: 2978
diff changeset
146
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
147 end_offset = ctx->output->offset;
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
148
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
149 /* write Content-Length headers */
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
150 str = t_strdup_printf("\nContent-Length: %s",
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
151 dec2str(end_offset - ctx->eoh_offset));
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
152 len = strlen(str);
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
153
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
154 /* flush manually here so that we don't confuse seek() errors with
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
155 buffer flushing errors */
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
156 if (o_stream_flush(ctx->output) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
157 return write_error(ctx);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
158 if (o_stream_seek(ctx->output, ctx->extra_hdr_offset +
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
159 ctx->space_end_idx - len) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
160 return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()");
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
161
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
162 if (o_stream_send(ctx->output, str, len) < 0 ||
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
163 o_stream_flush(ctx->output) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
164 return write_error(ctx);
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
165
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
166 if (o_stream_seek(ctx->output, end_offset) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
167 return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()");
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
168 return 0;
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
169 }
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
170
2892
62d53b49110d Changed mail_index_get_header() to return the header as return value because
Timo Sirainen <tss@iki.fi>
parents: 2877
diff changeset
171 static void mbox_save_init_sync(struct mbox_transaction_context *t)
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
172 {
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
173 struct mbox_mailbox *mbox = (struct mbox_mailbox *)t->ictx.ibox;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
174 struct mbox_save_context *ctx = t->save_ctx;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
175 const struct mail_index_header *hdr;
3221
af8fc972fe95 If want_mail = TRUE for mbox_save_init() and we sync the mbox, we'll have to
Timo Sirainen <tss@iki.fi>
parents: 3209
diff changeset
176 struct mail_index_view *view;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
177
3221
af8fc972fe95 If want_mail = TRUE for mbox_save_init() and we sync the mbox, we'll have to
Timo Sirainen <tss@iki.fi>
parents: 3209
diff changeset
178 /* open a new view to get the header. this is required if we just
af8fc972fe95 If want_mail = TRUE for mbox_save_init() and we sync the mbox, we'll have to
Timo Sirainen <tss@iki.fi>
parents: 3209
diff changeset
179 synced the mailbox so we can get updated next_uid. */
7028
78a75a5a5350 Refresh index when we want to know the next_uid, otherwise we might have
Timo Sirainen <tss@iki.fi>
parents: 7012
diff changeset
180 (void)mail_index_refresh(mbox->ibox.index);
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
181 view = mail_index_view_open(mbox->ibox.index);
3221
af8fc972fe95 If want_mail = TRUE for mbox_save_init() and we sync the mbox, we'll have to
Timo Sirainen <tss@iki.fi>
parents: 3209
diff changeset
182 hdr = mail_index_get_header(view);
2892
62d53b49110d Changed mail_index_get_header() to return the header as return value because
Timo Sirainen <tss@iki.fi>
parents: 2877
diff changeset
183
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
184 ctx->next_uid = hdr->next_uid;
5592
29ac17ec78ff Crashfix when saving mails
Timo Sirainen <tss@iki.fi>
parents: 5581
diff changeset
185 ctx->first_saved_uid = ctx->next_uid;
5124
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
186 ctx->uid_validity = hdr->uid_validity;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
187 ctx->synced = TRUE;
6511
fe5c19ffc119 Sync mbox when committing transaction only when saving messages to update
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
188 t->mails_saved = TRUE;
5572
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
189
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
190 mail_index_view_close(&view);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
191 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
192
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
193 static void status_flags_append(string_t *str, enum mail_flags flags,
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
194 const struct mbox_flag_type *flags_list)
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
195 {
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
196 int i;
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
197
3250
3b820e59610e Recent flag handling cleanups. Added some comments.
Timo Sirainen <tss@iki.fi>
parents: 3245
diff changeset
198 flags ^= MBOX_NONRECENT_KLUDGE;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
199 for (i = 0; flags_list[i].chr != 0; i++) {
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
200 if ((flags & flags_list[i].flag) != 0)
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
201 str_append_c(str, flags_list[i].chr);
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
202 }
3250
3b820e59610e Recent flag handling cleanups. Added some comments.
Timo Sirainen <tss@iki.fi>
parents: 3245
diff changeset
203 flags ^= MBOX_NONRECENT_KLUDGE;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
204 }
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
205
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
206 static void mbox_save_append_flag_headers(string_t *str, enum mail_flags flags)
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
207 {
7012
2f25031c4a84 When saving mail, it wasn't set \Recent when \Seen flag was also set.
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
208 /* write the Status: header always. It always gets added soon anyway. */
2f25031c4a84 When saving mail, it wasn't set \Recent when \Seen flag was also set.
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
209 str_append(str, "Status: ");
2f25031c4a84 When saving mail, it wasn't set \Recent when \Seen flag was also set.
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
210 status_flags_append(str, flags, mbox_status_flags);
2f25031c4a84 When saving mail, it wasn't set \Recent when \Seen flag was also set.
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
211 str_append_c(str, '\n');
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
212
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
213 if ((flags & XSTATUS_FLAGS_MASK) != 0) {
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
214 str_append(str, "X-Status: ");
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
215 status_flags_append(str, flags, mbox_xstatus_flags);
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
216 str_append_c(str, '\n');
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
217 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
218 }
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
219
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2986
diff changeset
220 static void
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2986
diff changeset
221 mbox_save_append_keyword_headers(struct mbox_save_context *ctx,
3086
66c44404f9a1 Keyword fixes.
Timo Sirainen <tss@iki.fi>
parents: 3016
diff changeset
222 struct mail_keywords *keywords)
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
223 {
2273
c48822c8713f Updated comment about how syncing is done, and s/extra space/padding/
Timo Sirainen <tss@iki.fi>
parents: 2261
diff changeset
224 unsigned char space[MBOX_HEADER_PADDING+1 +
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
225 sizeof("Content-Length: \n")-1 + MAX_INT_STRLEN];
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4412
diff changeset
226 const ARRAY_TYPE(keywords) *keyword_names_list;
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
227 const char *const *keyword_names;
3262
f1134d265a9d Don't crash while saving message if keywords aren't given..
Timo Sirainen <tss@iki.fi>
parents: 3260
diff changeset
228 unsigned int i, count, keyword_names_count;
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
229
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
230 keyword_names_list = mail_index_get_keywords(ctx->mbox->ibox.index);
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
231 keyword_names = array_get(keyword_names_list, &keyword_names_count);
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
232
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
233 str_append(ctx->headers, "X-Keywords:");
3262
f1134d265a9d Don't crash while saving message if keywords aren't given..
Timo Sirainen <tss@iki.fi>
parents: 3260
diff changeset
234 count = keywords == NULL ? 0 : keywords->count;
f1134d265a9d Don't crash while saving message if keywords aren't given..
Timo Sirainen <tss@iki.fi>
parents: 3260
diff changeset
235 for (i = 0; i < count; i++) {
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
236 i_assert(keywords->idx[i] < keyword_names_count);
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
237
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
238 str_append_c(ctx->headers, ' ');
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
239 str_append(ctx->headers, keyword_names[keywords->idx[i]]);
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3250
diff changeset
240 }
1209
539b7336b68a mbox: strip some headers when saving message. also always set Content-Length
Timo Sirainen <tss@iki.fi>
parents: 1039
diff changeset
241
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
242 memset(space, ' ', sizeof(space));
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
243 str_append_n(ctx->headers, space, sizeof(space));
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
244 ctx->space_end_idx = str_len(ctx->headers);
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
245 str_append_c(ctx->headers, '\n');
22
a946ce1f09b7 mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents: 13
diff changeset
246 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
248 static int
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
249 mbox_save_init_file(struct mbox_save_context *ctx,
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3662
diff changeset
250 struct mbox_transaction_context *t, bool want_mail)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 {
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
252 struct mbox_mailbox *mbox = ctx->mbox;
5613
f717fb4b31c0 Error handling rewrite.
Timo Sirainen <tss@iki.fi>
parents: 5592
diff changeset
253 struct mail_storage *storage = &mbox->storage->storage;
6583
104a8929ef7c When saving to empty mbox files, sync them first since it doesn't take
Timo Sirainen <tss@iki.fi>
parents: 6562
diff changeset
254 bool empty = FALSE;
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
255 int ret;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
256
8626
a9dd29e7dc4f Cleaned up read-only mailbox handling. Fixes a bug with Maildir syncing.
Timo Sirainen <tss@iki.fi>
parents: 8596
diff changeset
257 if (ctx->mbox->ibox.backend_readonly) {
5613
f717fb4b31c0 Error handling rewrite.
Timo Sirainen <tss@iki.fi>
parents: 5592
diff changeset
258 mail_storage_set_error(storage, MAIL_ERROR_PERM,
3245
6491dab63e54 Added input stream parameter to mailbox_open(). With mbox it now allows
Timo Sirainen <tss@iki.fi>
parents: 3221
diff changeset
259 "Read-only mbox");
6491dab63e54 Added input stream parameter to mailbox_open(). With mbox it now allows
Timo Sirainen <tss@iki.fi>
parents: 3221
diff changeset
260 return -1;
6491dab63e54 Added input stream parameter to mailbox_open(). With mbox it now allows
Timo Sirainen <tss@iki.fi>
parents: 3221
diff changeset
261 }
6491dab63e54 Added input stream parameter to mailbox_open(). With mbox it now allows
Timo Sirainen <tss@iki.fi>
parents: 3221
diff changeset
262
5572
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
263 if ((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS) != 0)
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
264 want_mail = TRUE;
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
265
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
266 if (ctx->append_offset == (uoff_t)-1) {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
267 /* first appended mail in this transaction */
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
268 if (mbox->mbox_lock_type != F_WRLCK) {
3662
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
269 if (mbox->mbox_lock_type == F_RDLCK) {
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
270 /* FIXME: we shouldn't fail here. it's just
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
271 a locking issue that should be possible to
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
272 fix.. */
5613
f717fb4b31c0 Error handling rewrite.
Timo Sirainen <tss@iki.fi>
parents: 5592
diff changeset
273 mail_storage_set_error(storage,
f717fb4b31c0 Error handling rewrite.
Timo Sirainen <tss@iki.fi>
parents: 5592
diff changeset
274 MAIL_ERROR_NOTPOSSIBLE,
3662
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
275 "Can't copy mails inside same mailbox");
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
276 return -1;
247501e81026 Instead of crashing when trying to copy mails within same mailbox, give an
Timo Sirainen <tss@iki.fi>
parents: 3565
diff changeset
277 }
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
278 if (mbox_lock(mbox, F_WRLCK, &t->mbox_lock_id) <= 0)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
279 return -1;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
280 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
281
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
282 if (mbox->mbox_fd == -1) {
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
283 if (mbox_file_open(mbox) < 0)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
284 return -1;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
285 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
286
5240
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
287 /* update mbox_sync_dirty state */
6583
104a8929ef7c When saving to empty mbox files, sync them first since it doesn't take
Timo Sirainen <tss@iki.fi>
parents: 6562
diff changeset
288 ret = mbox_sync_has_changed_full(mbox, TRUE, &empty);
5240
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
289 if (ret < 0)
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
290 return -1;
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
291 if (!want_mail && ret == 0) {
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
292 /* we're not required to assign UIDs for the appended
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
293 mails immediately. do it only if it doesn't require
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
294 syncing. */
117c9fd0b633 Keep track of the mbox dirty state better. Also when moving mails inside
Timo Sirainen <tss@iki.fi>
parents: 5168
diff changeset
295 mbox_save_init_sync(t);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
296 }
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
297 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
298
6583
104a8929ef7c When saving to empty mbox files, sync them first since it doesn't take
Timo Sirainen <tss@iki.fi>
parents: 6562
diff changeset
299 if (!ctx->synced && (want_mail || empty)) {
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
300 /* we'll need to assign UID for the mail immediately. */
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
301 if (mbox_sync(mbox, 0) < 0)
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
302 return -1;
2892
62d53b49110d Changed mail_index_get_header() to return the header as return value because
Timo Sirainen <tss@iki.fi>
parents: 2877
diff changeset
303 mbox_save_init_sync(t);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
304 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
305
5581
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
306 /* the syncing above could have changed the append offset */
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
307 if (ctx->append_offset == (uoff_t)-1) {
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
308 if (mbox_seek_to_end(ctx, &ctx->append_offset) < 0)
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
309 return -1;
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
310
6161
c62f7ee79446 Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents: 6142
diff changeset
311 ctx->output = o_stream_create_fd_file(mbox->mbox_fd,
c62f7ee79446 Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents: 6142
diff changeset
312 ctx->append_offset,
c62f7ee79446 Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents: 6142
diff changeset
313 FALSE);
7559
dd9d344ba140 mbox: When saving messages buffer the output until it's full, so if we die
Timo Sirainen <tss@iki.fi>
parents: 7490
diff changeset
314 o_stream_cork(ctx->output);
5581
ee2f0f1cd700 If we synced the mbox while saving the message (happens only with quota
Timo Sirainen <tss@iki.fi>
parents: 5580
diff changeset
315 }
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
316 return 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
317 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
318
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
319 static void save_header_callback(struct message_header_line *hdr,
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4681
diff changeset
320 bool *matched, struct mbox_save_context *ctx)
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
321 {
4681
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
322 if (hdr != NULL) {
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
323 if (strncmp(hdr->name, "From ", 5) == 0) {
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
324 /* we can't allow From_-lines in headers. there's no
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
325 legitimate reason for allowing them in any case,
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
326 so just drop them. */
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
327 *matched = TRUE;
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
328 return;
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
329 }
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
330
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
331 if (!*matched && ctx->mbox_md5_ctx != NULL)
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
332 mbox_md5_continue(ctx->mbox_md5_ctx, hdr);
cc110cb8c56b Filter out "From " lines from headers. There's no reason they should exist
Timo Sirainen <tss@iki.fi>
parents: 4562
diff changeset
333 }
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
334 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
335
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
336 static void mbox_save_x_delivery_id(struct mbox_save_context *ctx)
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
337 {
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
338 unsigned char md5_result[MD5_RESULTLEN];
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
339 buffer_t *buf;
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
340 string_t *str;
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
341 void *randbuf;
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
342
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
343 buf = buffer_create_dynamic(pool_datastack_create(), 256);
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
344 buffer_append(buf, &ioloop_time, sizeof(ioloop_time));
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
345 buffer_append(buf, &ioloop_timeval.tv_usec,
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
346 sizeof(ioloop_timeval.tv_usec));
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
347
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
348 randbuf = buffer_append_space_unsafe(buf, MBOX_DELIVERY_ID_RAND_BYTES);
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
349 random_fill_weak(randbuf, MBOX_DELIVERY_ID_RAND_BYTES);
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
350
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
351 md5_get_digest(buf->data, buf->used, md5_result);
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
352
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
353 str = t_str_new(128);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
354 str_append(str, "X-Delivery-ID: ");
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
355 base64_encode(md5_result, sizeof(md5_result), str);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
356 str_append_c(str, '\n');
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
357
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
358 ctx->x_delivery_id_header = i_strdup(str_c(str));
5167
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
359 }
b11b55f8912a If pop3_uidl_format=%m, add a unique X-Delivery-ID header to all saved
Timo Sirainen <tss@iki.fi>
parents: 5124
diff changeset
360
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
361 static struct istream *
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
362 mbox_save_get_input_stream(struct mbox_save_context *ctx, struct istream *input)
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
363 {
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
364 struct istream *filter, *ret, *cache_input, *streams[3];
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
365
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
366 /* filter out unwanted headers and keep track of headers' MD5 sum */
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
367 filter = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE |
7599
d5588b153cf6 mbox: We always add end-of-headers line while saving the message, so make
Timo Sirainen <tss@iki.fi>
parents: 7560
diff changeset
368 HEADER_FILTER_NO_CR |
d5588b153cf6 mbox: We always add end-of-headers line while saving the message, so make
Timo Sirainen <tss@iki.fi>
parents: 7560
diff changeset
369 HEADER_FILTER_ADD_MISSING_EOH,
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
370 mbox_save_drop_headers,
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
371 mbox_save_drop_headers_count,
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
372 save_header_callback, ctx);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
373
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
374 if ((ctx->mbox->storage->storage.flags &
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
375 MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) {
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
376 /* we're using MD5 sums to generate POP3 UIDLs.
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
377 clients don't like it much if there are duplicates,
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
378 so make sure that there can't be any by appending
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
379 our own X-Delivery-ID header. */
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
380 const char *hdr;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
381
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
382 T_BEGIN {
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
383 mbox_save_x_delivery_id(ctx);
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
384 } T_END;
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
385 hdr = ctx->x_delivery_id_header;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
386
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
387 streams[0] = i_stream_create_from_data(hdr, strlen(hdr));
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
388 streams[1] = filter;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
389 streams[2] = NULL;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
390 ret = i_stream_create_concat(streams);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
391 i_stream_unref(&filter);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
392 filter = ret;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
393 }
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
394
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
395 /* convert linefeeds to wanted format */
9002
9d0037a997f4 Initial commit for config rewrite.
Timo Sirainen <tss@iki.fi>
parents: 8626
diff changeset
396 ret = ctx->mbox->storage->storage.set->mail_save_crlf ?
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
397 i_stream_create_crlf(filter) : i_stream_create_lf(filter);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
398 i_stream_unref(&filter);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
399
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
400 if (ctx->mail != NULL) {
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
401 /* caching creates a tee stream */
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
402 cache_input = index_mail_cache_parse_init(ctx->mail, ret);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
403 i_stream_unref(&ret);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
404 ret = cache_input;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
405 }
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
406 return ret;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
407 }
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
408
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
409 struct mail_save_context *
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
410 mbox_save_alloc(struct mailbox_transaction_context *_t)
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
411 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
412 struct mbox_transaction_context *t =
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
413 (struct mbox_transaction_context *)_t;
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
414 struct mbox_mailbox *mbox = (struct mbox_mailbox *)t->ictx.ibox;
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
415 struct mbox_save_context *ctx;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
416
3209
923ff19873d4 Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents: 3086
diff changeset
417 i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
923ff19873d4 Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents: 3086
diff changeset
418
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
419 if (t->save_ctx != NULL)
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
420 return &t->save_ctx->ctx;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
421
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
422 ctx = t->save_ctx = i_new(struct mbox_save_context, 1);
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
423 ctx->ctx.transaction = &t->ictx.mailbox_ctx;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
424 ctx->mbox = mbox;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
425 ctx->trans = t->ictx.trans;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
426 ctx->append_offset = (uoff_t)-1;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
427 ctx->headers = str_new(default_pool, 512);
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
428 ctx->mail_offset = (uoff_t)-1;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
429 return &ctx->ctx;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
430 }
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
431
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
432 int mbox_save_begin(struct mail_save_context *_ctx, struct istream *input)
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
433 {
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
434 struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
435 struct mbox_transaction_context *t =
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
436 (struct mbox_transaction_context *)_ctx->transaction;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
437 enum mail_flags save_flags;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
438 uint64_t offset;
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
439
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
440 /* FIXME: we could write timezone_offset to From-line.. */
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
441 if (_ctx->received_date == (time_t)-1)
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
442 _ctx->received_date = ioloop_time;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
443
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
444 ctx->failed = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
445 ctx->seq = 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
446
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
447 if (mbox_save_init_file(ctx, t, _ctx->dest_mail != NULL) < 0) {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
448 ctx->failed = TRUE;
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
449 return -1;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
450 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
451
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
452 save_flags = (_ctx->flags & ~MAIL_RECENT) | MAIL_RECENT;
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
453 str_truncate(ctx->headers, 0);
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
454 if (ctx->synced) {
5580
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
455 if (ctx->mbox->mbox_save_md5)
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
456 ctx->mbox_md5_ctx = mbox_md5_init();
5124
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
457 if (ctx->output->offset == 0) {
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
458 /* writing the first mail. Insert X-IMAPbase as well. */
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
459 str_printfa(ctx->headers, "X-IMAPbase: %u %010u\n",
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
460 ctx->uid_validity, ctx->next_uid);
e008f09dc3c9 When saving a message to an empty mbox file, write X-IMAPbase header so the
Timo Sirainen <tss@iki.fi>
parents: 4918
diff changeset
461 }
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
462 str_printfa(ctx->headers, "X-UID: %u\n", ctx->next_uid);
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
463
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
464 mail_index_append(ctx->trans, ctx->next_uid, &ctx->seq);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
465 mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
7012
2f25031c4a84 When saving mail, it wasn't set \Recent when \Seen flag was also set.
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
466 save_flags & ~MAIL_RECENT);
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
467 if (_ctx->keywords != NULL) {
3471
138e242c53c9 Keywords weren't saved to index while saving.
Timo Sirainen <tss@iki.fi>
parents: 3470
diff changeset
468 mail_index_update_keywords(ctx->trans, ctx->seq,
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
469 MODIFY_REPLACE,
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
470 _ctx->keywords);
3471
138e242c53c9 Keywords weren't saved to index while saving.
Timo Sirainen <tss@iki.fi>
parents: 3470
diff changeset
471 }
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
472
2261
ba4f6d7b5a58 saving messages to empty mbox was buggy
Timo Sirainen <tss@iki.fi>
parents: 2224
diff changeset
473 offset = ctx->output->offset == 0 ? 0 :
ba4f6d7b5a58 saving messages to empty mbox was buggy
Timo Sirainen <tss@iki.fi>
parents: 2224
diff changeset
474 ctx->output->offset - 1;
2671
3b70ddb51771 Renamed "extra record info" and variations of it to "extension" or "ext" in
Timo Sirainen <tss@iki.fi>
parents: 2511
diff changeset
475 mail_index_update_ext(ctx->trans, ctx->seq,
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
476 ctx->mbox->mbox_ext_idx, &offset, NULL);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
477 ctx->next_uid++;
3464
0661239a7034 Cache mail headers when saving mails to mbox. We should cache everything,
Timo Sirainen <tss@iki.fi>
parents: 3348
diff changeset
478
3471
138e242c53c9 Keywords weren't saved to index while saving.
Timo Sirainen <tss@iki.fi>
parents: 3470
diff changeset
479 /* parse and cache the mail headers as we read it */
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
480 if (_ctx->dest_mail == NULL) {
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
481 if (ctx->mail == NULL) {
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
482 ctx->mail = mail_alloc(_ctx->transaction,
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
483 0, NULL);
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
484 }
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
485 _ctx->dest_mail = ctx->mail;
4268
7112aad504ae Changed mailbox_save_*() API a bit: Moved the struct mail *dest_mail to
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4193
diff changeset
486 }
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
487 mail_set_seq(_ctx->dest_mail, ctx->seq);
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
488 }
3250
3b820e59610e Recent flag handling cleanups. Added some comments.
Timo Sirainen <tss@iki.fi>
parents: 3245
diff changeset
489 mbox_save_append_flag_headers(ctx->headers, save_flags);
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
490 mbox_save_append_keyword_headers(ctx, _ctx->keywords);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
491 str_append_c(ctx->headers, '\n');
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
492
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
493 i_assert(ctx->mbox->mbox_lock_type == F_WRLCK);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
494
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
495 ctx->mail_offset = ctx->output->offset;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
496 ctx->eoh_offset = (uoff_t)-1;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
497 ctx->last_char = '\n';
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
498
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
499 if (write_from_line(ctx, _ctx->received_date, _ctx->from_envelope) < 0)
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
500 ctx->failed = TRUE;
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
501 else
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
502 ctx->input = mbox_save_get_input_stream(ctx, input);
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
503 return ctx->failed ? -1 : 0;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
504 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
505
6556
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
506 static int mbox_save_body_input(struct mbox_save_context *ctx)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
507 {
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
508 const unsigned char *data;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
509 size_t size;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
510
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
511 data = i_stream_get_data(ctx->input, &size);
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
512 if (size > 0) {
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
513 if (o_stream_send(ctx->output, data, size) < 0)
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
514 return write_error(ctx);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
515 ctx->last_char = data[size-1];
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
516 i_stream_skip(ctx->input, size);
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
517 }
6556
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
518 return 0;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
519 }
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
520
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
521 static int mbox_save_body(struct mbox_save_context *ctx)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
522 {
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
523 ssize_t ret;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
524
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
525 while ((ret = i_stream_read(ctx->input)) != -1) {
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
526 if (ctx->mail != NULL) {
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
527 /* i_stream_read() may have returned 0 at EOF
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
528 because of this parser */
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
529 index_mail_cache_parse_continue(ctx->mail);
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
530 }
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
531 if (ret == 0)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
532 return 0;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
533
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
534 if (mbox_save_body_input(ctx) < 0)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
535 return -1;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
536 }
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
537
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
538 if (ctx->last_char != '\n') {
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
539 /* if mail doesn't end with LF, we'll do that.
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
540 otherwise some mbox parsers don't like the result.
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
541 this makes it impossible to save a mail that doesn't
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
542 end with LF though. */
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
543 const char *linefeed =
9002
9d0037a997f4 Initial commit for config rewrite.
Timo Sirainen <tss@iki.fi>
parents: 8626
diff changeset
544 ctx->mbox->storage->storage.set->mail_save_crlf ?
6556
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
545 "\r\n" : "\n";
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
546 if (o_stream_send_str(ctx->output, linefeed) < 0)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
547 return write_error(ctx);
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
548 }
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
549 return 0;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
550 }
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
551
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
552 int mbox_save_continue(struct mail_save_context *_ctx)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
553 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
554 struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
555 const unsigned char *data;
6339
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
556 size_t i, size;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
557 ssize_t ret;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
558
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
559 if (ctx->failed)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
560 return -1;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
561
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
562 if (ctx->eoh_offset != (uoff_t)-1) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
563 /* writing body */
6556
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
564 return mbox_save_body(ctx);
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
565 }
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
566
8061
7f1389badb4c mbox: Saving may have truncated the mail being saved.
Timo Sirainen <tss@iki.fi>
parents: 8038
diff changeset
567 while ((ret = i_stream_read(ctx->input)) > 0) {
6337
83357f65cca4 Fixes to saving messages.
Timo Sirainen <tss@iki.fi>
parents: 6302
diff changeset
568 if (ctx->mail != NULL)
83357f65cca4 Fixes to saving messages.
Timo Sirainen <tss@iki.fi>
parents: 6302
diff changeset
569 index_mail_cache_parse_continue(ctx->mail);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
570
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
571 data = i_stream_get_data(ctx->input, &size);
6339
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
572 for (i = 0; i < size; i++) {
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
573 if (data[i] == '\n' &&
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
574 ((i == 0 && ctx->last_char == '\n') ||
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
575 (i > 0 && data[i-1] == '\n'))) {
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
576 /* end of headers. we don't need to worry about
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
577 CRs because they're dropped */
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
578 break;
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
579 }
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
580 }
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
581 if (i != size) {
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
582 /* found end of headers. write the rest of them
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
583 (not including the finishing empty line) */
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
584 if (o_stream_send(ctx->output, data, i) < 0)
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
585 return write_error(ctx);
6339
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
586 ctx->last_char = '\n';
301d0f8e4f91 Fixes to saving mails
Timo Sirainen <tss@iki.fi>
parents: 6337
diff changeset
587 i_stream_skip(ctx->input, i + 1);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
588 break;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
589 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
590
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
591 if (o_stream_send(ctx->output, data, size) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
592 return write_error(ctx);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
593 ctx->last_char = data[size-1];
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
594 i_stream_skip(ctx->input, size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
595 }
8061
7f1389badb4c mbox: Saving may have truncated the mail being saved.
Timo Sirainen <tss@iki.fi>
parents: 8038
diff changeset
596 if (ret == 0)
7f1389badb4c mbox: Saving may have truncated the mail being saved.
Timo Sirainen <tss@iki.fi>
parents: 8038
diff changeset
597 return 0;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
598
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
599 if (ctx->last_char != '\n') {
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
600 if (o_stream_send(ctx->output, "\n", 1) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
601 return write_error(ctx);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
602 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
603
2978
982e7432276f If mbox isn't synced, don't try to set message's md5sum because it just
Timo Sirainen <tss@iki.fi>
parents: 2973
diff changeset
604 if (ctx->mbox_md5_ctx) {
2973
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
605 unsigned char hdr_md5_sum[16];
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
606
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
607 if (ctx->x_delivery_id_header != NULL) {
5580
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
608 struct message_header_line hdr;
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
609
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
610 memset(&hdr, 0, sizeof(hdr));
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
611 hdr.name = ctx->x_delivery_id_header;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
612 hdr.name_len = sizeof("X-Delivery-ID")-1;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
613 hdr.middle = (const unsigned char *)hdr.name +
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
614 hdr.name_len;
5580
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
615 hdr.middle_len = 2;
6562
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
616 hdr.value = hdr.full_value =
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
617 hdr.middle + hdr.middle_len;
8917cf7fa8ba More fixes to handling mail saving.
Timo Sirainen <tss@iki.fi>
parents: 6556
diff changeset
618 hdr.value_len = strlen((const char *)hdr.value);
5580
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
619 mbox_md5_continue(ctx->mbox_md5_ctx, &hdr);
071d9bc5a075 If pop3_uidl_format=%m, it wasn't cached correctly when saving new messages
Timo Sirainen <tss@iki.fi>
parents: 5573
diff changeset
620 }
2973
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
621 mbox_md5_finish(ctx->mbox_md5_ctx, hdr_md5_sum);
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
622 mail_index_update_ext(ctx->trans, ctx->seq,
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
623 ctx->mbox->ibox.md5hdr_ext_idx,
2973
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
624 hdr_md5_sum, NULL);
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
625 }
32cc9186d8eb If we want MD5 sums in indexes, mail saving should also add them.
Timo Sirainen <tss@iki.fi>
parents: 2892
diff changeset
626
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
627 /* append our own headers and ending empty line */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
628 ctx->extra_hdr_offset = ctx->output->offset;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
629 if (o_stream_send(ctx->output, str_data(ctx->headers),
5281
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
630 str_len(ctx->headers)) < 0)
2712ba108fba o_stream_seek() may do buffer flushing internally and cause errors. Do
Timo Sirainen <tss@iki.fi>
parents: 5240
diff changeset
631 return write_error(ctx);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
632 ctx->eoh_offset = ctx->output->offset;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
633
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
634 /* write body */
6556
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
635 if (mbox_save_body_input(ctx) < 0)
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
636 return -1;
f9a4bd4ea2bb Fixed saving messages
Timo Sirainen <tss@iki.fi>
parents: 6528
diff changeset
637 return ctx->input->eof ? 0 : mbox_save_body(ctx);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
638 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
639
4268
7112aad504ae Changed mailbox_save_*() API a bit: Moved the struct mail *dest_mail to
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4193
diff changeset
640 int mbox_save_finish(struct mail_save_context *_ctx)
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
641 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
642 struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
643
7899
11727b49373e mbox: Don't crash if saving is aborted early.
Timo Sirainen <tss@iki.fi>
parents: 7599
diff changeset
644 if (ctx->output != NULL) {
11727b49373e mbox: Don't crash if saving is aborted early.
Timo Sirainen <tss@iki.fi>
parents: 7599
diff changeset
645 /* make sure everything is written */
11727b49373e mbox: Don't crash if saving is aborted early.
Timo Sirainen <tss@iki.fi>
parents: 7599
diff changeset
646 if (o_stream_flush(ctx->output) < 0)
8077
6d51328896d6 Added the concept of Global UIDs that are preserved across copies.
Timo Sirainen <tss@iki.fi>
parents: 8075
diff changeset
647 write_error(ctx);
7899
11727b49373e mbox: Don't crash if saving is aborted early.
Timo Sirainen <tss@iki.fi>
parents: 7599
diff changeset
648 }
7560
fedeb23a3d53 mbox: Be sure to flush output when writing to non-seekable "mboxes" (pipes).
Timo Sirainen <tss@iki.fi>
parents: 7559
diff changeset
649
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
650 ctx->finished = TRUE;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
651 if (!ctx->failed) {
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
652 T_BEGIN {
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
653 if (mbox_write_content_length(ctx) < 0 ||
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
654 mbox_append_lf(ctx) < 0)
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6583
diff changeset
655 ctx->failed = TRUE;
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7189
diff changeset
656 } T_END;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
657 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
658
7189
34057a03a357 If mail saving fails, don't try to update cache file (only to have the
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
659 if (ctx->mail != NULL) {
8075
8a068f879cd1 mailbox_save_init() API was split to multiple functions.
Timo Sirainen <tss@iki.fi>
parents: 8061
diff changeset
660 index_mail_cache_parse_deinit(ctx->mail, ctx->ctx.received_date,
7189
34057a03a357 If mail saving fails, don't try to update cache file (only to have the
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
661 !ctx->failed);
34057a03a357 If mail saving fails, don't try to update cache file (only to have the
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
662 }
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
663 if (ctx->input != NULL)
4070
71b8faa84ec6 Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents: 4044
diff changeset
664 i_stream_destroy(&ctx->input);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
665
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
666 if (ctx->failed && ctx->mail_offset != (uoff_t)-1) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
667 /* saving this mail failed - truncate back to beginning of it */
7559
dd9d344ba140 mbox: When saving messages buffer the output until it's full, so if we die
Timo Sirainen <tss@iki.fi>
parents: 7490
diff changeset
668 (void)o_stream_flush(ctx->output);
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
669 if (ftruncate(ctx->mbox->mbox_fd, (off_t)ctx->mail_offset) < 0)
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
670 mbox_set_syscall_error(ctx->mbox, "ftruncate()");
7559
dd9d344ba140 mbox: When saving messages buffer the output until it's full, so if we die
Timo Sirainen <tss@iki.fi>
parents: 7490
diff changeset
671 o_stream_seek(ctx->output, ctx->mail_offset);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
672 ctx->mail_offset = (uoff_t)-1;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
673 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
674
8077
6d51328896d6 Added the concept of Global UIDs that are preserved across copies.
Timo Sirainen <tss@iki.fi>
parents: 8075
diff changeset
675 index_save_context_free(_ctx);
4268
7112aad504ae Changed mailbox_save_*() API a bit: Moved the struct mail *dest_mail to
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4193
diff changeset
676 return ctx->failed ? -1 : 0;
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
677 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
678
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
679 void mbox_save_cancel(struct mail_save_context *_ctx)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
680 {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
681 struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
682
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
683 ctx->failed = TRUE;
4268
7112aad504ae Changed mailbox_save_*() API a bit: Moved the struct mail *dest_mail to
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4193
diff changeset
684 (void)mbox_save_finish(_ctx);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
685 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
686
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
687 static void mbox_transaction_save_deinit(struct mbox_save_context *ctx)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
688 {
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
689 if (ctx->output != NULL)
4070
71b8faa84ec6 Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents: 4044
diff changeset
690 o_stream_destroy(&ctx->output);
3464
0661239a7034 Cache mail headers when saving mails to mbox. We should cache everything,
Timo Sirainen <tss@iki.fi>
parents: 3348
diff changeset
691 if (ctx->mail != NULL)
6302
a8d5d826318b Call mail_alloc/mail_free, not index_mail_alloc/index_mail/free directly.
Timo Sirainen <tss@iki.fi>
parents: 6277
diff changeset
692 mail_free(&ctx->mail);
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
693 str_free(&ctx->headers);
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
694 i_free(ctx);
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
695 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
696
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
697 int mbox_transaction_save_commit(struct mbox_save_context *ctx)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
698 {
5572
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
699 struct mbox_transaction_context *t =
896845fbc4ed Added mailbox_transaction_commit_get_uids() which returns the UID range for
Timo Sirainen <tss@iki.fi>
parents: 5459
diff changeset
700 (struct mbox_transaction_context *)ctx->ctx.transaction;
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
701 struct mbox_mailbox *mbox = ctx->mbox;
4562
8b9933470cf8 After saving a mail with index being in synced state, update the sync_stamp
Timo Sirainen <tss@iki.fi>
parents: 4527
diff changeset
702 struct stat st;
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
703 int ret = 0;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
704
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
705 i_assert(ctx->finished);
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
706
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
707 if (fstat(mbox->mbox_fd, &st) < 0) {
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
708 mbox_set_syscall_error(mbox, "fstat()");
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
709 ret = -1;
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
710 }
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
711
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
712 if (ctx->synced) {
6267
3a1eed408cad mailbox_transaction_commit_get_uids() now returns also UIDVALIDITY. It's the
Timo Sirainen <tss@iki.fi>
parents: 6265
diff changeset
713 *t->ictx.saved_uid_validity = ctx->uid_validity;
5592
29ac17ec78ff Crashfix when saving mails
Timo Sirainen <tss@iki.fi>
parents: 5581
diff changeset
714 *t->ictx.first_saved_uid = ctx->first_saved_uid;
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
715 *t->ictx.last_saved_uid = ctx->next_uid - 1;
5592
29ac17ec78ff Crashfix when saving mails
Timo Sirainen <tss@iki.fi>
parents: 5581
diff changeset
716
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
717 mail_index_update_header(ctx->trans,
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
718 offsetof(struct mail_index_header, next_uid),
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3280
diff changeset
719 &ctx->next_uid, sizeof(ctx->next_uid), FALSE);
4562
8b9933470cf8 After saving a mail with index being in synced state, update the sync_stamp
Timo Sirainen <tss@iki.fi>
parents: 4527
diff changeset
720
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
721 if (ret == 0) {
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
722 mbox->mbox_hdr.sync_mtime = st.st_mtime;
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
723 mbox->mbox_hdr.sync_size = st.st_size;
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
724 mail_index_update_header_ext(ctx->trans,
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
725 mbox->mbox_ext_idx,
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
726 0, &mbox->mbox_hdr,
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
727 sizeof(mbox->mbox_hdr));
7490
e935b36b8b65 mbox: Always update sync_size when saving mails. We rely on sync_size for
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
728 }
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
729 }
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 2129
diff changeset
730
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
731 if (ret == 0 && ctx->orig_atime != st.st_atime) {
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
732 /* try to set atime back to its original value */
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
733 struct utimbuf buf;
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
734
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
735 buf.modtime = st.st_mtime;
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
736 buf.actime = ctx->orig_atime;
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
737 if (utime(mbox->path, &buf) < 0)
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
738 mbox_set_syscall_error(mbox, "utime()");
5741
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
739 }
7a57631e2d6c Preserve mbox files' atime when saving/syncing.
Timo Sirainen <tss@iki.fi>
parents: 5613
diff changeset
740
8527
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
741 if (!ctx->synced && mbox->mbox_fd != -1 &&
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
742 !mbox->mbox_writeonly && !mbox->ibox.fsync_disable) {
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
743 if (fdatasync(mbox->mbox_fd) < 0) {
6d07bedcdb80 mbox: Added a new index header where dirtyness state is stored.
Timo Sirainen <tss@iki.fi>
parents: 8244
diff changeset
744 mbox_set_syscall_error(mbox, "fdatasync()");
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
745 ret = -1;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
746 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
747 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
748
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
749 mbox_transaction_save_deinit(ctx);
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
750 return ret;
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
751 }
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
752
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
753 void mbox_transaction_save_rollback(struct mbox_save_context *ctx)
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
754 {
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
755 struct mbox_mailbox *mbox = ctx->mbox;
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
756
4044
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
757 if (!ctx->finished)
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
758 mbox_save_cancel(&ctx->ctx);
da1d65e064f8 mailbox_save_init() supports now returning failure. Quota plugin now checks
Timo Sirainen <timo.sirainen@movial.fi>
parents: 3879
diff changeset
759
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
760 if (ctx->append_offset != (uoff_t)-1 && mbox->mbox_fd != -1) {
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
761 i_assert(mbox->mbox_lock_type == F_WRLCK);
1978
6303ef092c5b mbox code compiles again, but syncing is only partially implemented so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
762
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
763 /* failed, truncate file back to original size.
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
764 output stream needs to be flushed before truncating
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
765 so unref() won't write anything. */
8244
327c893590c3 mbox: Don't crash if saving fails because of write error (out of disk space).
Timo Sirainen <tss@iki.fi>
parents: 8082
diff changeset
766 if (ctx->output != NULL)
327c893590c3 mbox: Don't crash if saving fails because of write error (out of disk space).
Timo Sirainen <tss@iki.fi>
parents: 8082
diff changeset
767 o_stream_flush(ctx->output);
562
ca988d72265b APPEND fixed for mbox
Timo Sirainen <tss@iki.fi>
parents: 532
diff changeset
768
3279
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
769 if (ftruncate(mbox->mbox_fd, (off_t)ctx->append_offset) < 0)
b698ae839a18 Moved mbox/maildir-specific variables from struct index_mailbox to
Timo Sirainen <tss@iki.fi>
parents: 3262
diff changeset
770 mbox_set_syscall_error(mbox, "ftruncate()");
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
771 }
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
772
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
773 mbox_transaction_save_deinit(ctx);
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
774 }