Mercurial > dovecot > core-2.2
annotate src/doveadm/dsync/dsync-mailbox-import.c @ 22713:cb108f786fb4
Updated copyright notices to include the year 2018.
author | Stephan Bosch <stephan.bosch@dovecot.fi> |
---|---|
date | Mon, 01 Jan 2018 22:42:08 +0100 |
parents | 400ff84f109d |
children | e33ad4efec00 |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
22549
diff
changeset
|
1 /* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ |
14584 | 2 |
3 #include "lib.h" | |
4 #include "array.h" | |
5 #include "hash.h" | |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
6 #include "str.h" |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
7 #include "hex-binary.h" |
14584 | 8 #include "istream.h" |
9 #include "seq-range-array.h" | |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
10 #include "imap-util.h" |
14584 | 11 #include "mail-storage-private.h" |
12 #include "mail-search-build.h" | |
13 #include "dsync-transaction-log-scan.h" | |
14 #include "dsync-mail.h" | |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
15 #include "dsync-mailbox.h" |
14584 | 16 #include "dsync-mailbox-import.h" |
17 | |
18 struct importer_mail { | |
19 const char *guid; | |
20 uint32_t uid; | |
21 }; | |
22 | |
23 struct importer_new_mail { | |
24 /* linked list of mails for this GUID */ | |
25 struct importer_new_mail *next; | |
26 /* if non-NULL, this mail exists in both local and remote. this link | |
27 points to the other side. */ | |
28 struct importer_new_mail *link; | |
29 | |
30 const char *guid; | |
31 struct dsync_mail_change *change; | |
32 | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
33 /* the final UID for the message */ |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
34 uint32_t final_uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
35 /* the original local UID, or 0 if exists only remotely */ |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
36 uint32_t local_uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
37 /* the original remote UID, or 0 if exists only remotely */ |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
38 uint32_t remote_uid; |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
39 /* UID for the mail in the virtual \All mailbox */ |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
40 uint32_t virtual_all_uid; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
41 |
14584 | 42 unsigned int uid_in_local:1; |
43 unsigned int uid_is_usable:1; | |
44 unsigned int skip:1; | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
45 unsigned int expunged:1; |
14584 | 46 unsigned int copy_failed:1; |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
47 unsigned int saved:1; |
14584 | 48 }; |
49 | |
15668
583ea6b63c5d
dsync: Added a quick way to debug unexpected changes.
Timo Sirainen <tss@iki.fi>
parents:
15667
diff
changeset
|
50 /* for quickly testing that two-way sync doesn't actually do any unexpected |
583ea6b63c5d
dsync: Added a quick way to debug unexpected changes.
Timo Sirainen <tss@iki.fi>
parents:
15667
diff
changeset
|
51 modifications. */ |
583ea6b63c5d
dsync: Added a quick way to debug unexpected changes.
Timo Sirainen <tss@iki.fi>
parents:
15667
diff
changeset
|
52 #define IMPORTER_DEBUG_CHANGE(importer) /*i_assert(!importer->master_brain)*/ |
583ea6b63c5d
dsync: Added a quick way to debug unexpected changes.
Timo Sirainen <tss@iki.fi>
parents:
15667
diff
changeset
|
53 |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
54 HASH_TABLE_DEFINE_TYPE(guid_new_mail, const char *, struct importer_new_mail *); |
14923
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
55 HASH_TABLE_DEFINE_TYPE(uid_new_mail, void *, struct importer_new_mail *); |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
56 |
14584 | 57 struct dsync_mailbox_importer { |
58 pool_t pool; | |
59 struct mailbox *box; | |
60 uint32_t last_common_uid; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
61 uint64_t last_common_modseq, last_common_pvt_modseq; |
14584 | 62 uint32_t remote_uid_next; |
63 uint32_t remote_first_recent_uid; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
64 uint64_t remote_highest_modseq, remote_highest_pvt_modseq; |
18177
f393f63764e0
dsync: Added -t <timestamp> parameter to save only mails newer than <timestamp>
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
65 time_t sync_since_timestamp; |
20831
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
66 time_t sync_until_timestamp; |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
67 uoff_t sync_max_size; |
19318
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
68 enum mailbox_transaction_flags transaction_flags; |
19646
25f06710e671
dsync: When comparing headers' hashes to match messages, try to normalize the input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
69 unsigned int hdr_hash_version; |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
70 unsigned int commit_msgs_interval; |
14584 | 71 |
22549
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
72 const char *const *hashed_headers; |
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
73 |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
74 enum mail_flags sync_flag; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
75 const char *sync_keyword; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
76 bool sync_flag_dontwant; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
77 |
14584 | 78 struct mailbox_transaction_context *trans, *ext_trans; |
79 struct mail_search_context *search_ctx; | |
80 struct mail *mail, *ext_mail; | |
81 | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
82 struct mailbox *virtual_all_box; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
83 struct mailbox_transaction_context *virtual_trans; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
84 struct mail *virtual_mail; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
85 |
14584 | 86 struct mail *cur_mail; |
87 const char *cur_guid; | |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
88 const char *cur_hdr_hash; |
14584 | 89 |
90 /* UID => struct dsync_mail_change */ | |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
91 HASH_TABLE_TYPE(dsync_uid_mail_change) local_changes; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
92 HASH_TABLE_TYPE(dsync_attr_change) local_attr_changes; |
14584 | 93 |
94 ARRAY_TYPE(seq_range) maybe_expunge_uids; | |
14920
a097ef0a9d6d
Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name
Timo Sirainen <tss@iki.fi>
parents:
14918
diff
changeset
|
95 ARRAY(struct dsync_mail_change *) maybe_saves; |
14584 | 96 |
97 /* GUID => struct importer_new_mail */ | |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
98 HASH_TABLE_TYPE(guid_new_mail) import_guids; |
14584 | 99 /* UID => struct importer_new_mail */ |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
100 HASH_TABLE_TYPE(uid_new_mail) import_uids; |
14584 | 101 |
14920
a097ef0a9d6d
Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name
Timo Sirainen <tss@iki.fi>
parents:
14918
diff
changeset
|
102 ARRAY(struct importer_new_mail *) newmails; |
14584 | 103 ARRAY_TYPE(uint32_t) wanted_uids; |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
104 ARRAY_TYPE(uint32_t) saved_uids; |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
105 uint32_t highest_wanted_uid; |
14584 | 106 |
14920
a097ef0a9d6d
Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name
Timo Sirainen <tss@iki.fi>
parents:
14918
diff
changeset
|
107 ARRAY(struct dsync_mail_request) mail_requests; |
14584 | 108 unsigned int mail_request_idx; |
109 | |
110 uint32_t prev_uid, next_local_seq, local_uid_next; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
111 uint64_t local_initial_highestmodseq, local_initial_highestpvtmodseq; |
16539
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
112 unsigned int import_pos, import_count; |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
113 unsigned int first_unsaved_idx, saves_since_commit; |
14584 | 114 |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
115 enum mail_error mail_error; |
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
116 |
14584 | 117 unsigned int failed:1; |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
118 unsigned int require_full_resync:1; |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
119 unsigned int debug:1; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
120 unsigned int stateful_import:1; |
14584 | 121 unsigned int last_common_uid_found:1; |
122 unsigned int cur_uid_has_change:1; | |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
123 unsigned int cur_mail_skip:1; |
14584 | 124 unsigned int local_expunged_guids_set:1; |
125 unsigned int new_uids_assigned:1; | |
126 unsigned int want_mail_requests:1; | |
127 unsigned int master_brain:1; | |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
128 unsigned int revert_local_changes:1; |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
129 unsigned int mails_have_guids:1; |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
130 unsigned int mails_use_guid128:1; |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
131 unsigned int delete_mailbox:1; |
20595
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
132 unsigned int empty_hdr_workaround:1; |
14584 | 133 }; |
134 | |
20208
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
135 static const char *dsync_mail_change_type_names[] = { |
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
136 "save", "expunge", "flag-change" |
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
137 }; |
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
138 |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
139 static bool dsync_mailbox_save_newmails(struct dsync_mailbox_importer *importer, |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
140 const struct dsync_mail *mail, |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
141 struct importer_new_mail *all_newmails, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
142 bool remote_mail); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
143 static int dsync_mailbox_import_commit(struct dsync_mailbox_importer *importer, |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
144 bool final); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
145 |
17272 | 146 static void ATTR_FORMAT(2, 3) |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
147 imp_debug(struct dsync_mailbox_importer *importer, const char *fmt, ...) |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
148 { |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
149 va_list args; |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
150 |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
151 if (importer->debug) T_BEGIN { |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
152 va_start(args, fmt); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
153 i_debug("brain %c: Import %s: %s", |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
154 importer->master_brain ? 'M' : 'S', |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
155 mailbox_get_vname(importer->box), |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
156 t_strdup_vprintf(fmt, args)); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
157 va_end(args); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
158 } T_END; |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
159 } |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
160 |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
161 static void |
20072
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
162 dsync_import_unexpected_state(struct dsync_mailbox_importer *importer, |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
163 const char *error) |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
164 { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
165 if (!importer->stateful_import) { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
166 i_error("Mailbox %s: %s", mailbox_get_vname(importer->box), |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
167 error); |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
168 } else { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
169 i_warning("Mailbox %s doesn't match previous state: %s " |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
170 "(dsync must be run again without the state)", |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
171 mailbox_get_vname(importer->box), error); |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
172 } |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
173 importer->require_full_resync = TRUE; |
20072
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
174 } |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
175 |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
176 static void |
14584 | 177 dsync_mailbox_import_search_init(struct dsync_mailbox_importer *importer) |
178 { | |
179 struct mail_search_args *search_args; | |
180 struct mail_search_arg *sarg; | |
181 | |
182 search_args = mail_search_build_init(); | |
183 sarg = mail_search_build_add(search_args, SEARCH_UIDSET); | |
184 p_array_init(&sarg->value.seqset, search_args->pool, 128); | |
185 seq_range_array_add_range(&sarg->value.seqset, | |
186 importer->last_common_uid+1, (uint32_t)-1); | |
187 | |
188 importer->search_ctx = | |
189 mailbox_search_init(importer->trans, search_args, NULL, | |
190 0, NULL); | |
191 mail_search_args_unref(&search_args); | |
192 | |
193 if (mailbox_search_next(importer->search_ctx, &importer->cur_mail)) | |
194 importer->next_local_seq = importer->cur_mail->seq; | |
195 /* this flag causes cur_guid to be looked up later */ | |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
196 importer->cur_mail_skip = TRUE; |
14584 | 197 } |
198 | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
199 static void |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
200 dsync_mailbox_import_transaction_begin(struct dsync_mailbox_importer *importer) |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
201 { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
202 const enum mailbox_transaction_flags ext_trans_flags = |
19318
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
203 importer->transaction_flags | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
204 MAILBOX_TRANSACTION_FLAG_EXTERNAL | |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
205 MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
206 |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
207 importer->trans = mailbox_transaction_begin(importer->box, |
19318
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
208 importer->transaction_flags); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
209 importer->ext_trans = mailbox_transaction_begin(importer->box, |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
210 ext_trans_flags); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
211 importer->mail = mail_alloc(importer->trans, 0, NULL); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
212 importer->ext_mail = mail_alloc(importer->ext_trans, 0, NULL); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
213 } |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
214 |
14584 | 215 struct dsync_mailbox_importer * |
216 dsync_mailbox_import_init(struct mailbox *box, | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
217 struct mailbox *virtual_all_box, |
14584 | 218 struct dsync_transaction_log_scan *log_scan, |
219 uint32_t last_common_uid, | |
220 uint64_t last_common_modseq, | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
221 uint64_t last_common_pvt_modseq, |
14584 | 222 uint32_t remote_uid_next, |
223 uint32_t remote_first_recent_uid, | |
224 uint64_t remote_highest_modseq, | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
225 uint64_t remote_highest_pvt_modseq, |
20831
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
226 time_t sync_since_timestamp, |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
227 time_t sync_until_timestamp, |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
228 uoff_t sync_max_size, |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
229 const char *sync_flag, |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
230 unsigned int commit_msgs_interval, |
22264
e95435889161
dsync: Use header hashing version 3
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22043
diff
changeset
|
231 enum dsync_mailbox_import_flags flags, |
22549
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
232 unsigned int hdr_hash_version, |
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
233 const char *const *hashed_headers) |
14584 | 234 { |
235 struct dsync_mailbox_importer *importer; | |
236 struct mailbox_status status; | |
237 pool_t pool; | |
238 | |
239 pool = pool_alloconly_create(MEMPOOL_GROWING"dsync mailbox importer", | |
240 10240); | |
241 importer = p_new(pool, struct dsync_mailbox_importer, 1); | |
242 importer->pool = pool; | |
243 importer->box = box; | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
244 importer->virtual_all_box = virtual_all_box; |
14584 | 245 importer->last_common_uid = last_common_uid; |
246 importer->last_common_modseq = last_common_modseq; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
247 importer->last_common_pvt_modseq = last_common_pvt_modseq; |
14584 | 248 importer->last_common_uid_found = |
249 last_common_uid != 0 || last_common_modseq != 0; | |
250 importer->remote_uid_next = remote_uid_next; | |
251 importer->remote_first_recent_uid = remote_first_recent_uid; | |
252 importer->remote_highest_modseq = remote_highest_modseq; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
253 importer->remote_highest_pvt_modseq = remote_highest_pvt_modseq; |
18177
f393f63764e0
dsync: Added -t <timestamp> parameter to save only mails newer than <timestamp>
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
254 importer->sync_since_timestamp = sync_since_timestamp; |
20831
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
255 importer->sync_until_timestamp = sync_until_timestamp; |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
256 importer->sync_max_size = sync_max_size; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
257 importer->stateful_import = importer->last_common_uid_found; |
22549
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
258 importer->hashed_headers = hashed_headers; |
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
259 |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
260 if (sync_flag != NULL) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
261 if (sync_flag[0] == '-') { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
262 importer->sync_flag_dontwant = TRUE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
263 sync_flag++; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
264 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
265 if (sync_flag[0] == '\\') |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
266 importer->sync_flag = imap_parse_system_flag(sync_flag); |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
267 else |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
268 importer->sync_keyword = p_strdup(pool, sync_flag); |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
269 } |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
270 importer->commit_msgs_interval = commit_msgs_interval; |
19318
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
271 importer->transaction_flags = MAILBOX_TRANSACTION_FLAG_SYNC; |
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
272 if ((flags & DSYNC_MAILBOX_IMPORT_FLAG_NO_NOTIFY) != 0) |
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
273 importer->transaction_flags |= MAILBOX_TRANSACTION_FLAG_NO_NOTIFY; |
14584 | 274 |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
275 hash_table_create(&importer->import_guids, pool, 0, str_hash, strcmp); |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
276 hash_table_create_direct(&importer->import_uids, pool, 0); |
14584 | 277 i_array_init(&importer->maybe_expunge_uids, 16); |
278 i_array_init(&importer->maybe_saves, 128); | |
279 i_array_init(&importer->newmails, 128); | |
280 i_array_init(&importer->wanted_uids, 128); | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
281 i_array_init(&importer->saved_uids, 128); |
14584 | 282 |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
283 dsync_mailbox_import_transaction_begin(importer); |
14584 | 284 |
285 if ((flags & DSYNC_MAILBOX_IMPORT_FLAG_WANT_MAIL_REQUESTS) != 0) { | |
286 i_array_init(&importer->mail_requests, 128); | |
287 importer->want_mail_requests = TRUE; | |
288 } | |
289 importer->master_brain = | |
290 (flags & DSYNC_MAILBOX_IMPORT_FLAG_MASTER_BRAIN) != 0; | |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
291 importer->revert_local_changes = |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
292 (flags & DSYNC_MAILBOX_IMPORT_FLAG_REVERT_LOCAL_CHANGES) != 0; |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
293 importer->debug = (flags & DSYNC_MAILBOX_IMPORT_FLAG_DEBUG) != 0; |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
294 importer->mails_have_guids = |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
295 (flags & DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS) != 0; |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
296 importer->mails_use_guid128 = |
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
297 (flags & DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128) != 0; |
22264
e95435889161
dsync: Use header hashing version 3
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22043
diff
changeset
|
298 importer->hdr_hash_version = hdr_hash_version; |
20595
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
299 importer->empty_hdr_workaround = |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
300 (flags & DSYNC_MAILBOX_IMPORT_FLAG_EMPTY_HDR_WORKAROUND) != 0; |
14584 | 301 |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
302 mailbox_get_open_status(importer->box, STATUS_UIDNEXT | |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
303 STATUS_HIGHESTMODSEQ | STATUS_HIGHESTPVTMODSEQ, |
14584 | 304 &status); |
305 importer->local_uid_next = status.uidnext; | |
306 importer->local_initial_highestmodseq = status.highest_modseq; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
307 importer->local_initial_highestpvtmodseq = status.highest_pvt_modseq; |
14584 | 308 dsync_mailbox_import_search_init(importer); |
309 | |
20072
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
310 if (!importer->stateful_import) |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
311 ; |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
312 else if (importer->local_uid_next <= last_common_uid) { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
313 dsync_import_unexpected_state(importer, t_strdup_printf( |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
314 "local UIDNEXT %u <= last common UID %u", |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
315 importer->local_uid_next, last_common_uid)); |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
316 } else if (importer->local_initial_highestmodseq < last_common_modseq) { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
317 dsync_import_unexpected_state(importer, t_strdup_printf( |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
318 "local HIGHESTMODSEQ %llu < last common HIGHESTMODSEQ %llu", |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
319 (unsigned long long)importer->local_initial_highestmodseq, |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
320 (unsigned long long)last_common_modseq)); |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
321 } else if (importer->local_initial_highestpvtmodseq < last_common_pvt_modseq) { |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
322 dsync_import_unexpected_state(importer, t_strdup_printf( |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
323 "local HIGHESTMODSEQ %llu < last common HIGHESTMODSEQ %llu", |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
324 (unsigned long long)importer->local_initial_highestpvtmodseq, |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
325 (unsigned long long)last_common_pvt_modseq)); |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
326 } |
18d1fcb14277
dsync: Improved detecting state state string.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19696
diff
changeset
|
327 |
14926
9c69df65af7b
Simplified hash table union now that it again works only with pointers.
Timo Sirainen <tss@iki.fi>
parents:
14923
diff
changeset
|
328 importer->local_changes = dsync_transaction_log_scan_get_hash(log_scan); |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
329 importer->local_attr_changes = dsync_transaction_log_scan_get_attr_hash(log_scan); |
14584 | 330 return importer; |
331 } | |
332 | |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
333 static int |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
334 dsync_mailbox_import_lookup_attr(struct dsync_mailbox_importer *importer, |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
335 enum mail_attribute_type type, const char *key, |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
336 struct dsync_mailbox_attribute **attr_r) |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
337 { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
338 struct dsync_mailbox_attribute lookup_attr, *attr; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
339 const struct dsync_mailbox_attribute *attr_change; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
340 struct mail_attribute_value value; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
341 |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
342 *attr_r = NULL; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
343 |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
344 if (mailbox_attribute_get_stream(importer->trans, type, key, &value) < 0) { |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
345 i_error("Mailbox %s: Failed to get attribute %s: %s", |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
346 mailbox_get_vname(importer->box), key, |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
347 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
348 &importer->mail_error)); |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
349 importer->failed = TRUE; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
350 return -1; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
351 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
352 |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
353 lookup_attr.type = type; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
354 lookup_attr.key = key; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
355 |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
356 attr_change = hash_table_lookup(importer->local_attr_changes, |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
357 &lookup_attr); |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
358 if (attr_change == NULL && |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
359 value.value == NULL && value.value_stream == NULL) { |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
360 /* we have no knowledge of this attribute */ |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
361 return 0; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
362 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
363 attr = t_new(struct dsync_mailbox_attribute, 1); |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
364 attr->type = type; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
365 attr->key = key; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
366 attr->value = value.value; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
367 attr->value_stream = value.value_stream; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
368 attr->last_change = value.last_change; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
369 if (attr_change != NULL) { |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
370 attr->deleted = attr_change->deleted && |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
371 !DSYNC_ATTR_HAS_VALUE(attr); |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
372 attr->modseq = attr_change->modseq; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
373 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
374 *attr_r = attr; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
375 return 0; |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
376 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
377 |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
378 static int |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
379 dsync_istreams_cmp(struct istream *input1, struct istream *input2, int *cmp_r) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
380 { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
381 const unsigned char *data1, *data2; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
382 size_t size1, size2, size; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
383 |
16088 | 384 *cmp_r = -1; /* quiet gcc */ |
385 | |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
386 for (;;) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
387 (void)i_stream_read_data(input1, &data1, &size1, 0); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
388 (void)i_stream_read_data(input2, &data2, &size2, 0); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
389 |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
390 if (size1 == 0 || size2 == 0) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
391 break; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
392 size = I_MIN(size1, size2); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
393 *cmp_r = memcmp(data1, data2, size); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
394 if (*cmp_r != 0) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
395 return 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
396 i_stream_skip(input1, size); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
397 i_stream_skip(input2, size); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
398 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
399 if (input1->stream_errno != 0) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
400 errno = input1->stream_errno; |
16940
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
401 i_error("read(%s) failed: %s", i_stream_get_name(input1), |
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
402 i_stream_get_error(input1)); |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
403 return -1; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
404 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
405 if (input2->stream_errno != 0) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
406 errno = input2->stream_errno; |
16940
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
407 i_error("read(%s) failed: %s", i_stream_get_name(input2), |
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
408 i_stream_get_error(input2)); |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
409 return -1; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
410 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
411 if (size1 == 0 && size2 == 0) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
412 *cmp_r = 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
413 else |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
414 *cmp_r = size1 == 0 ? -1 : 1; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
415 return 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
416 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
417 |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
418 static int |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
419 dsync_attributes_cmp_values(const struct dsync_mailbox_attribute *attr1, |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
420 const struct dsync_mailbox_attribute *attr2, |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
421 int *cmp_r) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
422 { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
423 struct istream *input1, *input2; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
424 int ret; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
425 |
17345
24d27f7da7b2
dsync: Make static analyzer happier (hopefully)
Timo Sirainen <tss@iki.fi>
parents:
17296
diff
changeset
|
426 i_assert(attr1->value_stream != NULL || attr1->value != NULL); |
24d27f7da7b2
dsync: Make static analyzer happier (hopefully)
Timo Sirainen <tss@iki.fi>
parents:
17296
diff
changeset
|
427 i_assert(attr2->value_stream != NULL || attr2->value != NULL); |
24d27f7da7b2
dsync: Make static analyzer happier (hopefully)
Timo Sirainen <tss@iki.fi>
parents:
17296
diff
changeset
|
428 |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
429 if (attr1->value != NULL && attr2->value != NULL) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
430 *cmp_r = strcmp(attr1->value, attr2->value); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
431 return 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
432 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
433 /* at least one of them is a stream. make both of them streams. */ |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
434 input1 = attr1->value_stream != NULL ? attr1->value_stream : |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
435 i_stream_create_from_data(attr1->value, strlen(attr1->value)); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
436 input2 = attr2->value_stream != NULL ? attr2->value_stream : |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
437 i_stream_create_from_data(attr2->value, strlen(attr2->value)); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
438 i_stream_seek(input1, 0); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
439 i_stream_seek(input2, 0); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
440 ret = dsync_istreams_cmp(input1, input2, cmp_r); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
441 if (attr1->value_stream == NULL) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
442 i_stream_unref(&input1); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
443 if (attr2->value_stream == NULL) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
444 i_stream_unref(&input2); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
445 return ret; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
446 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
447 |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
448 static int |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
449 dsync_attributes_cmp(const struct dsync_mailbox_attribute *attr, |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
450 const struct dsync_mailbox_attribute *local_attr, |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
451 int *cmp_r) |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
452 { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
453 if (DSYNC_ATTR_HAS_VALUE(attr) && |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
454 !DSYNC_ATTR_HAS_VALUE(local_attr)) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
455 /* remote has a value and local doesn't -> use it */ |
16055
8b5c098cbd0f
dsync: Fixed attribute value comparisons.
Timo Sirainen <tss@iki.fi>
parents:
16052
diff
changeset
|
456 *cmp_r = 1; |
8b5c098cbd0f
dsync: Fixed attribute value comparisons.
Timo Sirainen <tss@iki.fi>
parents:
16052
diff
changeset
|
457 return 0; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
458 } else if (!DSYNC_ATTR_HAS_VALUE(attr) && |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
459 DSYNC_ATTR_HAS_VALUE(local_attr)) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
460 /* remote doesn't have a value, bt local does -> skip */ |
16055
8b5c098cbd0f
dsync: Fixed attribute value comparisons.
Timo Sirainen <tss@iki.fi>
parents:
16052
diff
changeset
|
461 *cmp_r = -1; |
8b5c098cbd0f
dsync: Fixed attribute value comparisons.
Timo Sirainen <tss@iki.fi>
parents:
16052
diff
changeset
|
462 return 0; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
463 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
464 |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
465 return dsync_attributes_cmp_values(attr, local_attr, cmp_r); |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
466 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
467 |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
468 static int |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
469 dsync_mailbox_import_attribute_real(struct dsync_mailbox_importer *importer, |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
470 const struct dsync_mailbox_attribute *attr, |
18999
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
471 const struct dsync_mailbox_attribute *local_attr, |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
472 const char **result_r) |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
473 { |
16046
3e4c4f9c230b
dsync: Set last_change timestamp for unset attributes.
Timo Sirainen <tss@iki.fi>
parents:
16044
diff
changeset
|
474 struct mail_attribute_value value; |
16259
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
475 int cmp; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
476 bool ignore = FALSE; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
477 |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
478 i_assert(DSYNC_ATTR_HAS_VALUE(attr) || attr->deleted); |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
479 |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
480 if (attr->deleted && |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
481 (local_attr == NULL || !DSYNC_ATTR_HAS_VALUE(local_attr))) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
482 /* attribute doesn't exist on either side -> ignore */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
483 *result_r = "Nonexistent in both sides"; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
484 return 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
485 } |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
486 if (local_attr == NULL) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
487 /* we haven't seen this locally -> use whatever remote has */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
488 *result_r = "Nonexistent locally"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
489 } else if (local_attr->modseq <= importer->last_common_modseq && |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
490 attr->modseq > importer->last_common_modseq && |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
491 importer->last_common_modseq > 0) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
492 /* we're doing incremental syncing, and we can see that the |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
493 attribute was changed remotely, but not locally -> use it */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
494 *result_r = "Changed remotely"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
495 } else if (local_attr->modseq > importer->last_common_modseq && |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
496 attr->modseq <= importer->last_common_modseq && |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
497 importer->last_common_modseq > 0) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
498 /* we're doing incremental syncing, and we can see that the |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
499 attribute was changed locally, but not remotely -> ignore */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
500 *result_r = "Changed locally"; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
501 ignore = TRUE; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
502 } else if (attr->last_change > local_attr->last_change) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
503 /* remote has a newer timestamp -> use it */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
504 *result_r = "Remote has newer timestamp"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
505 } else if (attr->last_change < local_attr->last_change) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
506 /* remote has an older timestamp -> ignore */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
507 *result_r = "Local has newer timestamp"; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
508 ignore = TRUE; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
509 } else { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
510 /* the timestamps are the same. now we're down to guessing |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
511 the right answer, unless the values are actually equal, |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
512 so check that first. next try to use modseqs, but if even |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
513 they are the same, fallback to just picking one based on the |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
514 value. */ |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
515 if (dsync_attributes_cmp(attr, local_attr, &cmp) < 0) { |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
516 importer->mail_error = MAIL_ERROR_TEMP; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
517 importer->failed = TRUE; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
518 return -1; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
519 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
520 if (cmp == 0) { |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
521 /* identical scripts */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
522 *result_r = "Unchanged value"; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
523 return 0; |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
524 } |
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
525 |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
526 if (attr->modseq > local_attr->modseq) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
527 /* remote has a higher modseq -> use it */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
528 *result_r = "Remote has newer modseq"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
529 } else if (attr->modseq < local_attr->modseq) { |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
530 /* remote has an older modseq -> ignore */ |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
531 *result_r = "Local has newer modseq"; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
532 ignore = TRUE; |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
533 } else if (cmp < 0) { |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
534 ignore = TRUE; |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
535 *result_r = "Value changed, but unknown which is newer - picking local"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
536 } else { |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
537 *result_r = "Value changed, but unknown which is newer - picking remote"; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
538 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
539 } |
18999
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
540 if (ignore) |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
541 return 0; |
16044
2396eb0a3e3f
lib-storage: mailbox_attribute_set() now uses struct mail_attribute_value.
Timo Sirainen <tss@iki.fi>
parents:
16025
diff
changeset
|
542 |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21267
diff
changeset
|
543 i_zero(&value); |
16046
3e4c4f9c230b
dsync: Set last_change timestamp for unset attributes.
Timo Sirainen <tss@iki.fi>
parents:
16044
diff
changeset
|
544 value.value = attr->value; |
16052
0e5a359b7b7f
lib-storage: Mailbox attributes can now be accessed via istreams.
Timo Sirainen <tss@iki.fi>
parents:
16046
diff
changeset
|
545 value.value_stream = attr->value_stream; |
16046
3e4c4f9c230b
dsync: Set last_change timestamp for unset attributes.
Timo Sirainen <tss@iki.fi>
parents:
16044
diff
changeset
|
546 value.last_change = attr->last_change; |
16259
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
547 if (mailbox_attribute_set(importer->trans, attr->type, |
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
548 attr->key, &value) < 0) { |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
549 i_error("Mailbox %s: Failed to set attribute %s: %s", |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
550 mailbox_get_vname(importer->box), attr->key, |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
551 mailbox_get_last_internal_error(importer->box, NULL)); |
16259
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
552 /* the attributes aren't vital, don't fail everything just |
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
553 because of them. */ |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
554 } |
16259
8da591260f7c
dsync: Don't fail the sync if attribute couldn't be set.
Timo Sirainen <tss@iki.fi>
parents:
16256
diff
changeset
|
555 return 0; |
16025
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
556 } |
c6082de4bf5b
dsync: Added support for syncing mailbox attributes.
Timo Sirainen <tss@iki.fi>
parents:
15841
diff
changeset
|
557 |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
558 int dsync_mailbox_import_attribute(struct dsync_mailbox_importer *importer, |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
559 const struct dsync_mailbox_attribute *attr) |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
560 { |
18999
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
561 struct dsync_mailbox_attribute *local_attr; |
19000
de8af4d857d3
dsync: Compiler warning fix to previous change.
Timo Sirainen <tss@iki.fi>
parents:
18999
diff
changeset
|
562 const char *result = ""; |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
563 int ret; |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
564 |
18999
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
565 if (dsync_mailbox_import_lookup_attr(importer, attr->type, |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
566 attr->key, &local_attr) < 0) |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
567 ret = -1; |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
568 else { |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
569 ret = dsync_mailbox_import_attribute_real(importer, attr, |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
570 local_attr, &result); |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
571 if (local_attr != NULL && local_attr->value_stream != NULL) |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
572 i_stream_unref(&local_attr->value_stream); |
d5cddaa5ca92
dsync: Fixed memory leaks when importing attributes whose values were in istreams.
Timo Sirainen <tss@iki.fi>
parents:
18371
diff
changeset
|
573 } |
18018
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
574 imp_debug(importer, "Import attribute %s: %s", attr->key, |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
575 ret < 0 ? "failed" : result); |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
576 return ret; |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
577 } |
4155055df7a9
dsync: Added debug logging for attribute importing
Timo Sirainen <tss@iki.fi>
parents:
17982
diff
changeset
|
578 |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
579 static void dsync_mail_error(struct dsync_mailbox_importer *importer, |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
580 struct mail *mail, const char *field) |
14584 | 581 { |
582 const char *errstr; | |
583 enum mail_error error; | |
584 | |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
585 errstr = mailbox_get_last_internal_error(importer->box, &error); |
14584 | 586 if (error == MAIL_ERROR_EXPUNGED) |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
587 return; |
14584 | 588 |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
589 i_error("Mailbox %s: Can't lookup %s for UID=%u: %s", |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
590 mailbox_get_vname(mail->box), field, mail->uid, errstr); |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
591 importer->mail_error = error; |
14584 | 592 importer->failed = TRUE; |
593 } | |
594 | |
595 static bool | |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
596 dsync_mail_change_guid_equals(struct dsync_mailbox_importer *importer, |
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
597 const struct dsync_mail_change *change, |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
598 const char *guid, const char **cmp_guid_r) |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
599 { |
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
600 guid_128_t guid_128, change_guid_128; |
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
601 |
16995
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
602 if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { |
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
603 if (guid_128_from_string(change->guid, change_guid_128) < 0) |
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
604 i_unreached(); |
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
605 } else if (importer->mails_use_guid128) { |
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
606 mail_generate_guid_128_hash(change->guid, change_guid_128); |
df2b27885c9d
dsync: Fix to 128bit GUID syncing
Timo Sirainen <tss@iki.fi>
parents:
16977
diff
changeset
|
607 } else { |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
608 if (cmp_guid_r != NULL) |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
609 *cmp_guid_r = change->guid; |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
610 return strcmp(change->guid, guid) == 0; |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
611 } |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
612 |
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
613 mail_generate_guid_128_hash(guid, guid_128); |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
614 if (memcmp(change_guid_128, guid_128, GUID_128_SIZE) != 0) { |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
615 if (cmp_guid_r != NULL) { |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
616 *cmp_guid_r = t_strdup_printf("%s(guid128, orig=%s)", |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
617 binary_to_hex(change_guid_128, sizeof(change_guid_128)), |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
618 change->guid); |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
619 } |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
620 return FALSE; |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
621 } |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
622 return TRUE; |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
623 } |
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
624 |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
625 static int |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
626 importer_try_next_mail(struct dsync_mailbox_importer *importer, |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
627 uint32_t wanted_uid) |
14584 | 628 { |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
629 struct mail_private *pmail; |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
630 const char *hdr_hash; |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
631 |
14584 | 632 if (importer->cur_mail == NULL) { |
633 /* end of search */ | |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
634 return -1; |
14584 | 635 } |
636 while (importer->cur_mail->seq < importer->next_local_seq || | |
637 importer->cur_mail->uid < wanted_uid) { | |
638 if (!importer->cur_uid_has_change && | |
639 !importer->last_common_uid_found) { | |
640 /* this message exists locally, but remote didn't send | |
641 expunge-change for it. if the message's | |
642 uid <= last-common-uid, it should be deleted */ | |
14676
69ba6977bed8
seq_range_array_add() API changed. Added other functions to provide the less common use cases.
Timo Sirainen <tss@iki.fi>
parents:
14675
diff
changeset
|
643 seq_range_array_add(&importer->maybe_expunge_uids, |
14584 | 644 importer->cur_mail->uid); |
645 } | |
646 | |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
647 importer->cur_mail_skip = FALSE; |
14584 | 648 if (!mailbox_search_next(importer->search_ctx, |
649 &importer->cur_mail)) { | |
650 importer->cur_mail = NULL; | |
651 importer->cur_guid = NULL; | |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
652 importer->cur_hdr_hash = NULL; |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
653 return -1; |
14584 | 654 } |
655 importer->cur_uid_has_change = FALSE; | |
656 } | |
17464
203b3a6f508f
Removed pointless NULL checks.
Timo Sirainen <tss@iki.fi>
parents:
17345
diff
changeset
|
657 importer->cur_uid_has_change = importer->cur_mail->uid == wanted_uid; |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
658 if (importer->mails_have_guids) { |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
659 if (mail_get_special(importer->cur_mail, MAIL_FETCH_GUID, |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
660 &importer->cur_guid) < 0) { |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
661 dsync_mail_error(importer, importer->cur_mail, "GUID"); |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
662 return 0; |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
663 } |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
664 } else { |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
665 if (dsync_mail_get_hdr_hash(importer->cur_mail, |
19646
25f06710e671
dsync: When comparing headers' hashes to match messages, try to normalize the input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
666 importer->hdr_hash_version, |
22549
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
667 importer->hashed_headers, |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
668 &hdr_hash) < 0) { |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
669 dsync_mail_error(importer, importer->cur_mail, |
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
670 "header hash"); |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
671 return 0; |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
672 } |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
673 pmail = (struct mail_private *)importer->cur_mail; |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
674 importer->cur_hdr_hash = p_strdup(pmail->pool, hdr_hash); |
16117
494d1a69fc1c
dsync: Crashfix when importing from storage without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16088
diff
changeset
|
675 importer->cur_guid = ""; |
14584 | 676 } |
677 /* make sure next_local_seq gets updated in case we came here | |
678 because of min_uid */ | |
679 importer->next_local_seq = importer->cur_mail->seq; | |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
680 return 1; |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
681 } |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
682 |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
683 static bool |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
684 importer_next_mail(struct dsync_mailbox_importer *importer, uint32_t wanted_uid) |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
685 { |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
686 int ret; |
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
687 |
17261
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
688 for (;;) { |
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
689 T_BEGIN { |
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
690 ret = importer_try_next_mail(importer, wanted_uid); |
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
691 } T_END; |
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
692 if (ret != 0 || importer->failed) |
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
693 break; |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
694 importer->next_local_seq = importer->cur_mail->seq + 1; |
17261
ddf374a36057
dsync: Fixed high data stack memory usage
Timo Sirainen <tss@iki.fi>
parents:
17174
diff
changeset
|
695 } |
15770
516a337480f4
dsync: Avoid possibly long function recursion.
Timo Sirainen <tss@iki.fi>
parents:
15766
diff
changeset
|
696 return ret > 0; |
14584 | 697 } |
698 | |
699 static int | |
700 importer_mail_cmp(const struct importer_mail *m1, | |
701 const struct importer_mail *m2) | |
702 { | |
703 int ret; | |
704 | |
705 if (m1->guid == NULL) | |
706 return 1; | |
707 if (m2->guid == NULL) | |
708 return -1; | |
709 | |
710 ret = strcmp(m1->guid, m2->guid); | |
711 if (ret != 0) | |
712 return ret; | |
713 | |
714 if (m1->uid < m2->uid) | |
715 return -1; | |
716 if (m1->uid > m2->uid) | |
717 return 1; | |
718 return 0; | |
719 } | |
720 | |
721 static void newmail_link(struct dsync_mailbox_importer *importer, | |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
722 struct importer_new_mail *newmail, uint32_t remote_uid) |
14584 | 723 { |
724 struct importer_new_mail *first_mail, **last, *mail, *link = NULL; | |
725 | |
726 if (*newmail->guid != '\0') { | |
727 first_mail = hash_table_lookup(importer->import_guids, | |
728 newmail->guid); | |
729 if (first_mail == NULL) { | |
730 /* first mail for this GUID */ | |
731 hash_table_insert(importer->import_guids, | |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
732 newmail->guid, newmail); |
14584 | 733 return; |
734 } | |
735 } else { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
736 if (remote_uid == 0) { |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
737 /* mail exists only locally. we don't want to request |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
738 it, and we'll assume it has no duplicate |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
739 instances. */ |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
740 return; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
741 } |
14584 | 742 first_mail = hash_table_lookup(importer->import_uids, |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
743 POINTER_CAST(remote_uid)); |
14584 | 744 if (first_mail == NULL) { |
745 /* first mail for this UID */ | |
746 hash_table_insert(importer->import_uids, | |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
747 POINTER_CAST(remote_uid), newmail); |
14584 | 748 return; |
749 } | |
750 } | |
751 /* 1) add the newmail to the end of the linked list | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
752 2) find our link |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
753 |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
754 FIXME: this loop is slow if the same GUID has a ton of instances. |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
755 Could it be improved in some way? */ |
14584 | 756 last = &first_mail->next; |
757 for (mail = first_mail; mail != NULL; mail = mail->next) { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
758 if (mail->final_uid == newmail->final_uid) |
14584 | 759 mail->uid_is_usable = TRUE; |
760 if (link == NULL && mail->link == NULL && | |
761 mail->uid_in_local != newmail->uid_in_local) | |
762 link = mail; | |
763 last = &mail->next; | |
764 } | |
765 *last = newmail; | |
766 if (link != NULL && newmail->link == NULL) { | |
767 link->link = newmail; | |
768 newmail->link = link; | |
769 } | |
770 } | |
771 | |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
772 static void |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
773 dsync_mailbox_revert_existing_uid(struct dsync_mailbox_importer *importer, |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
774 uint32_t uid, const char *reason) |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
775 { |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
776 i_assert(importer->revert_local_changes); |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
777 |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
778 /* UID either already exists or UIDNEXT is too high. we can't set the |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
779 wanted UID, so we'll need to delete the whole mailbox and resync */ |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
780 i_warning("Deleting mailbox '%s': UID=%u already exists locally for a different mail: %s", |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
781 mailbox_get_vname(importer->box), uid, reason); |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
782 importer->delete_mailbox = TRUE; |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
783 importer->mail_error = MAIL_ERROR_TEMP; |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
784 importer->failed = TRUE; |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
785 } |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
786 |
14584 | 787 static bool dsync_mailbox_try_save_cur(struct dsync_mailbox_importer *importer, |
788 struct dsync_mail_change *save_change) | |
789 { | |
790 struct importer_mail m1, m2; | |
791 struct importer_new_mail *newmail; | |
792 int diff; | |
793 bool remote_saved; | |
794 | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21267
diff
changeset
|
795 i_zero(&m1); |
14584 | 796 if (importer->cur_mail != NULL) { |
15754
f6a8f0522634
dsync: Minor fix to deciding when to use GUIDs vs. header hashes.
Timo Sirainen <tss@iki.fi>
parents:
15753
diff
changeset
|
797 m1.guid = importer->mails_have_guids ? |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
798 importer->cur_guid : importer->cur_hdr_hash; |
14584 | 799 m1.uid = importer->cur_mail->uid; |
800 } | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21267
diff
changeset
|
801 i_zero(&m2); |
14584 | 802 if (save_change != NULL) { |
15754
f6a8f0522634
dsync: Minor fix to deciding when to use GUIDs vs. header hashes.
Timo Sirainen <tss@iki.fi>
parents:
15753
diff
changeset
|
803 m2.guid = importer->mails_have_guids ? |
f6a8f0522634
dsync: Minor fix to deciding when to use GUIDs vs. header hashes.
Timo Sirainen <tss@iki.fi>
parents:
15753
diff
changeset
|
804 save_change->guid : save_change->hdr_hash; |
14584 | 805 m2.uid = save_change->uid; |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
806 i_assert(save_change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE); |
14584 | 807 } |
808 | |
20595
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
809 if (importer->empty_hdr_workaround && !importer->mails_have_guids && |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
810 importer->cur_mail != NULL && save_change != NULL && |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
811 (dsync_mail_hdr_hash_is_empty(m1.guid) || |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
812 dsync_mail_hdr_hash_is_empty(m2.guid))) { |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
813 /* one of the headers is empty. assume it's broken and that |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
814 the header matches what we have currently. */ |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
815 diff = 0; |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
816 } else { |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
817 diff = importer_mail_cmp(&m1, &m2); |
40ce04c672a4
dsync: Add support for features
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20262
diff
changeset
|
818 } |
14584 | 819 if (diff < 0) { |
820 /* add a record for local mail */ | |
14675 | 821 i_assert(importer->cur_mail != NULL); |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
822 if (importer->revert_local_changes) { |
20191
8e6442a0888f
doveadm backup: Fixed unnecessary mailbox deletion.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20127
diff
changeset
|
823 if (save_change == NULL && |
8e6442a0888f
doveadm backup: Fixed unnecessary mailbox deletion.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20127
diff
changeset
|
824 importer->cur_mail->uid >= importer->remote_uid_next) { |
19670
b467f6d24fd5
doveadm backup: If local mailbox has more mails than remote, detect and delete it earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19660
diff
changeset
|
825 dsync_mailbox_revert_existing_uid(importer, importer->cur_mail->uid, |
20191
8e6442a0888f
doveadm backup: Fixed unnecessary mailbox deletion.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20127
diff
changeset
|
826 t_strdup_printf("higher than remote's UIDs (remote UIDNEXT=%u)", importer->remote_uid_next)); |
19670
b467f6d24fd5
doveadm backup: If local mailbox has more mails than remote, detect and delete it earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19660
diff
changeset
|
827 return TRUE; |
b467f6d24fd5
doveadm backup: If local mailbox has more mails than remote, detect and delete it earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19660
diff
changeset
|
828 } |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
829 mail_expunge(importer->cur_mail); |
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
830 importer->cur_mail_skip = TRUE; |
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
831 importer->next_local_seq++; |
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
832 return FALSE; |
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
833 } |
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
834 newmail = p_new(importer->pool, struct importer_new_mail, 1); |
14584 | 835 newmail->guid = p_strdup(importer->pool, importer->cur_guid); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
836 newmail->final_uid = importer->cur_mail->uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
837 newmail->local_uid = importer->cur_mail->uid; |
14584 | 838 newmail->uid_in_local = TRUE; |
839 newmail->uid_is_usable = | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
840 newmail->final_uid >= importer->remote_uid_next; |
14584 | 841 remote_saved = FALSE; |
842 } else if (diff > 0) { | |
14675 | 843 i_assert(save_change != NULL); |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
844 newmail = p_new(importer->pool, struct importer_new_mail, 1); |
14584 | 845 newmail->guid = save_change->guid; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
846 newmail->final_uid = save_change->uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
847 newmail->remote_uid = save_change->uid; |
14584 | 848 newmail->uid_in_local = FALSE; |
849 newmail->uid_is_usable = | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
850 newmail->final_uid >= importer->local_uid_next; |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
851 if (!newmail->uid_is_usable && importer->revert_local_changes) { |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
852 dsync_mailbox_revert_existing_uid(importer, newmail->final_uid, |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
853 t_strdup_printf("UID >= local UIDNEXT=%u", importer->local_uid_next)); |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
854 return TRUE; |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
855 } |
14584 | 856 remote_saved = TRUE; |
857 } else { | |
858 /* identical */ | |
14675 | 859 i_assert(importer->cur_mail != NULL); |
860 i_assert(save_change != NULL); | |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
861 newmail = p_new(importer->pool, struct importer_new_mail, 1); |
14584 | 862 newmail->guid = save_change->guid; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
863 newmail->final_uid = importer->cur_mail->uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
864 newmail->local_uid = importer->cur_mail->uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
865 newmail->remote_uid = save_change->uid; |
14584 | 866 newmail->uid_in_local = TRUE; |
867 newmail->uid_is_usable = TRUE; | |
868 newmail->link = newmail; | |
869 remote_saved = TRUE; | |
870 } | |
871 | |
872 if (newmail->uid_in_local) { | |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
873 importer->cur_mail_skip = TRUE; |
14584 | 874 importer->next_local_seq++; |
875 } | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
876 /* NOTE: assumes save_change is allocated from importer pool */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
877 newmail->change = save_change; |
14584 | 878 |
879 array_append(&importer->newmails, &newmail, 1); | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
880 newmail_link(importer, newmail, |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
881 save_change == NULL ? 0 : save_change->uid); |
14584 | 882 return remote_saved; |
883 } | |
884 | |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14584
diff
changeset
|
885 static bool ATTR_NULL(2) |
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14584
diff
changeset
|
886 dsync_mailbox_try_save(struct dsync_mailbox_importer *importer, |
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14584
diff
changeset
|
887 struct dsync_mail_change *save_change) |
14584 | 888 { |
15661
940414cea18d
dsync backup: Old unwanted messages weren't deleted as they should have.
Timo Sirainen <tss@iki.fi>
parents:
15658
diff
changeset
|
889 if (importer->cur_mail_skip) { |
14584 | 890 if (!importer_next_mail(importer, 0) && save_change == NULL) |
891 return FALSE; | |
892 } | |
893 return dsync_mailbox_try_save_cur(importer, save_change); | |
894 } | |
895 | |
896 static void dsync_mailbox_save(struct dsync_mailbox_importer *importer, | |
897 struct dsync_mail_change *save_change) | |
898 { | |
899 while (!dsync_mailbox_try_save(importer, save_change)) ; | |
900 } | |
901 | |
902 static bool | |
903 dsync_import_set_mail(struct dsync_mailbox_importer *importer, | |
904 const struct dsync_mail_change *change) | |
905 { | |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
906 const char *guid, *cmp_guid; |
14584 | 907 |
908 if (!mail_set_uid(importer->mail, change->uid)) | |
909 return FALSE; | |
910 if (change->guid == NULL) { | |
911 /* GUID is unknown */ | |
912 return TRUE; | |
913 } | |
914 if (*change->guid == '\0') { | |
915 /* backend doesn't support GUIDs. if hdr_hash is set, we could | |
916 verify it, but since this message really is supposed to | |
917 match, it's probably too much trouble. */ | |
918 return TRUE; | |
919 } | |
920 | |
921 /* verify that GUID matches, just in case */ | |
922 if (mail_get_special(importer->mail, MAIL_FETCH_GUID, &guid) < 0) { | |
923 dsync_mail_error(importer, importer->mail, "GUID"); | |
924 return FALSE; | |
925 } | |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
926 if (!dsync_mail_change_guid_equals(importer, change, guid, &cmp_guid)) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
927 dsync_import_unexpected_state(importer, t_strdup_printf( |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
928 "Unexpected GUID mismatch for UID=%u: %s != %s", |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
929 change->uid, guid, cmp_guid)); |
14584 | 930 return FALSE; |
931 } | |
932 return TRUE; | |
933 } | |
934 | |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
935 static bool dsync_check_cur_guid(struct dsync_mailbox_importer *importer, |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
936 const struct dsync_mail_change *change) |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
937 { |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
938 const char *cmp_guid; |
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
939 |
16558
f3b9325509fd
dsync: Fixed syncing when one of the backends supported GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16556
diff
changeset
|
940 if (change->guid == NULL || change->guid[0] == '\0' || |
f3b9325509fd
dsync: Fixed syncing when one of the backends supported GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16556
diff
changeset
|
941 importer->cur_guid[0] == '\0') |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
942 return TRUE; |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
943 if (!dsync_mail_change_guid_equals(importer, change, |
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
944 importer->cur_guid, &cmp_guid)) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
945 dsync_import_unexpected_state(importer, t_strdup_printf( |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
946 "Unexpected GUID mismatch (2) for UID=%u: %s != %s", |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
947 change->uid, importer->cur_guid, cmp_guid)); |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
948 return FALSE; |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
949 } |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
950 return TRUE; |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
951 } |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
952 |
14584 | 953 static void |
954 merge_flags(uint32_t local_final, uint32_t local_add, uint32_t local_remove, | |
955 uint32_t remote_final, uint32_t remote_add, uint32_t remote_remove, | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
956 uint32_t pvt_mask, bool prefer_remote, bool prefer_pvt_remote, |
15698
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
957 uint32_t *change_add_r, uint32_t *change_remove_r, |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
958 bool *remote_changed, bool *remote_pvt_changed) |
14584 | 959 { |
960 uint32_t combined_add, combined_remove, conflict_flags; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
961 uint32_t local_wanted, remote_wanted, conflict_pvt_flags; |
14584 | 962 |
963 /* resolve conflicts */ | |
964 conflict_flags = local_add & remote_remove; | |
965 if (conflict_flags != 0) { | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
966 conflict_pvt_flags = conflict_flags & pvt_mask; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
967 conflict_flags &= ~pvt_mask; |
14584 | 968 if (prefer_remote) |
969 local_add &= ~conflict_flags; | |
970 else | |
971 remote_remove &= ~conflict_flags; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
972 if (prefer_pvt_remote) |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
973 local_add &= ~conflict_pvt_flags; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
974 else |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
975 remote_remove &= ~conflict_pvt_flags; |
14584 | 976 } |
15841
7f5c29a81f03
dsync: Assert-crashfix for handling conflicting private flags.
Timo Sirainen <tss@iki.fi>
parents:
15824
diff
changeset
|
977 conflict_flags = local_remove & remote_add; |
14584 | 978 if (conflict_flags != 0) { |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
979 conflict_pvt_flags = conflict_flags & pvt_mask; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
980 conflict_flags &= ~pvt_mask; |
14584 | 981 if (prefer_remote) |
982 local_remove &= ~conflict_flags; | |
983 else | |
984 remote_add &= ~conflict_flags; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
985 if (prefer_pvt_remote) |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
986 local_remove &= ~conflict_pvt_flags; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
987 else |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
988 remote_add &= ~conflict_pvt_flags; |
14584 | 989 } |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
990 |
14584 | 991 combined_add = local_add|remote_add; |
992 combined_remove = local_remove|remote_remove; | |
993 i_assert((combined_add & combined_remove) == 0); | |
994 | |
15699
9b7d80a8db44
dsync: If both local and remote have the same message flags, don't go changing them.
Timo Sirainen <tss@iki.fi>
parents:
15698
diff
changeset
|
995 /* don't change flags that are currently identical in both sides */ |
9b7d80a8db44
dsync: If both local and remote have the same message flags, don't go changing them.
Timo Sirainen <tss@iki.fi>
parents:
15698
diff
changeset
|
996 conflict_flags = local_final ^ remote_final; |
9b7d80a8db44
dsync: If both local and remote have the same message flags, don't go changing them.
Timo Sirainen <tss@iki.fi>
parents:
15698
diff
changeset
|
997 combined_add &= conflict_flags; |
9b7d80a8db44
dsync: If both local and remote have the same message flags, don't go changing them.
Timo Sirainen <tss@iki.fi>
parents:
15698
diff
changeset
|
998 combined_remove &= conflict_flags; |
9b7d80a8db44
dsync: If both local and remote have the same message flags, don't go changing them.
Timo Sirainen <tss@iki.fi>
parents:
15698
diff
changeset
|
999 |
14584 | 1000 /* see if there are conflicting final flags */ |
1001 local_wanted = (local_final|combined_add) & ~combined_remove; | |
1002 remote_wanted = (remote_final|combined_add) & ~combined_remove; | |
1003 | |
1004 conflict_flags = local_wanted ^ remote_wanted; | |
1005 if (conflict_flags != 0) { | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1006 if (prefer_remote && prefer_pvt_remote) |
14584 | 1007 local_wanted = remote_wanted; |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1008 else if (prefer_remote && !prefer_pvt_remote) { |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1009 local_wanted = (local_wanted & pvt_mask) | |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1010 (remote_wanted & ~pvt_mask); |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1011 } else if (!prefer_remote && prefer_pvt_remote) { |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1012 local_wanted = (local_wanted & ~pvt_mask) | |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1013 (remote_wanted & pvt_mask); |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1014 } |
14584 | 1015 } |
1016 | |
1017 *change_add_r = local_wanted & ~local_final; | |
1018 *change_remove_r = local_final & ~local_wanted; | |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1019 if ((local_wanted & ~pvt_mask) != (remote_final & ~pvt_mask)) |
15698
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1020 *remote_changed = TRUE; |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1021 if ((local_wanted & pvt_mask) != (remote_final & pvt_mask)) |
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1022 *remote_pvt_changed = TRUE; |
14584 | 1023 } |
1024 | |
1025 static bool | |
1026 keyword_find(ARRAY_TYPE(const_string) *keywords, const char *name, | |
1027 unsigned int *idx_r) | |
1028 { | |
1029 const char *const *names; | |
1030 unsigned int i, count; | |
1031 | |
1032 names = array_get(keywords, &count); | |
1033 for (i = 0; i < count; i++) { | |
1034 if (strcmp(names[i], name) == 0) { | |
1035 *idx_r = i; | |
1036 return TRUE; | |
1037 } | |
1038 } | |
1039 return FALSE; | |
1040 } | |
1041 | |
1042 static void keywords_append(ARRAY_TYPE(const_string) *dest, | |
1043 const ARRAY_TYPE(const_string) *keywords, | |
1044 uint32_t bits, unsigned int start_idx) | |
1045 { | |
1046 const char *const *namep; | |
1047 unsigned int i; | |
1048 | |
1049 for (i = 0; i < 32; i++) { | |
1050 if ((bits & (1U << i)) == 0) | |
1051 continue; | |
1052 | |
1053 namep = array_idx(keywords, start_idx+i); | |
1054 array_append(dest, namep, 1); | |
1055 } | |
1056 } | |
1057 | |
1058 static void | |
1059 merge_keywords(struct mail *mail, const ARRAY_TYPE(const_string) *local_changes, | |
1060 const ARRAY_TYPE(const_string) *remote_changes, | |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1061 bool prefer_remote, |
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1062 bool *remote_changed, bool *remote_pvt_changed) |
14584 | 1063 { |
1064 /* local_changes and remote_changes are assumed to have no | |
1065 duplicates names */ | |
1066 uint32_t *local_add, *local_remove, *local_final; | |
1067 uint32_t *remote_add, *remote_remove, *remote_final; | |
1068 uint32_t *change_add, *change_remove; | |
1069 ARRAY_TYPE(const_string) all_keywords, add_keywords, remove_keywords; | |
1070 const char *const *changes, *name, *const *local_keywords; | |
1071 struct mail_keywords *kw; | |
1072 unsigned int i, count, name_idx, array_size; | |
1073 | |
1074 local_keywords = mail_get_keywords(mail); | |
1075 | |
1076 /* we'll assign a common index for each keyword name and place | |
1077 the changes to separate bit arrays. */ | |
1078 if (array_is_created(remote_changes)) | |
1079 changes = array_get(remote_changes, &count); | |
1080 else { | |
1081 changes = NULL; | |
1082 count = 0; | |
1083 } | |
1084 | |
1085 array_size = str_array_length(local_keywords) + count; | |
1086 if (array_is_created(local_changes)) | |
1087 array_size += array_count(local_changes); | |
1088 if (array_size == 0) { | |
1089 /* this message has no keywords */ | |
1090 return; | |
1091 } | |
1092 t_array_init(&all_keywords, array_size); | |
1093 t_array_init(&add_keywords, array_size); | |
1094 t_array_init(&remove_keywords, array_size); | |
1095 | |
1096 /* @UNSAFE: create large enough arrays to fit all keyword indexes. */ | |
1097 array_size = (array_size+31)/32; | |
1098 local_add = t_new(uint32_t, array_size); | |
1099 local_remove = t_new(uint32_t, array_size); | |
1100 local_final = t_new(uint32_t, array_size); | |
1101 remote_add = t_new(uint32_t, array_size); | |
1102 remote_remove = t_new(uint32_t, array_size); | |
1103 remote_final = t_new(uint32_t, array_size); | |
1104 change_add = t_new(uint32_t, array_size); | |
1105 change_remove = t_new(uint32_t, array_size); | |
1106 | |
1107 /* get remote changes */ | |
1108 for (i = 0; i < count; i++) { | |
1109 name = changes[i]+1; | |
1110 name_idx = array_count(&all_keywords); | |
1111 array_append(&all_keywords, &name, 1); | |
1112 | |
1113 switch (changes[i][0]) { | |
1114 case KEYWORD_CHANGE_ADD: | |
1115 remote_add[name_idx/32] |= 1U << (name_idx%32); | |
15700
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1116 break; |
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1117 case KEYWORD_CHANGE_REMOVE: |
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1118 remote_remove[name_idx/32] |= 1U << (name_idx%32); |
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1119 break; |
14584 | 1120 case KEYWORD_CHANGE_FINAL: |
1121 remote_final[name_idx/32] |= 1U << (name_idx%32); | |
1122 break; | |
15700
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1123 case KEYWORD_CHANGE_ADD_AND_FINAL: |
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1124 remote_add[name_idx/32] |= 1U << (name_idx%32); |
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1125 remote_final[name_idx/32] |= 1U << (name_idx%32); |
14584 | 1126 break; |
1127 } | |
1128 } | |
1129 | |
1130 /* get local changes. use existing indexes for names when they exist. */ | |
1131 if (array_is_created(local_changes)) | |
1132 changes = array_get(local_changes, &count); | |
1133 else { | |
1134 changes = NULL; | |
1135 count = 0; | |
1136 } | |
1137 for (i = 0; i < count; i++) { | |
1138 name = changes[i]+1; | |
1139 if (!keyword_find(&all_keywords, name, &name_idx)) { | |
1140 name_idx = array_count(&all_keywords); | |
1141 array_append(&all_keywords, &name, 1); | |
1142 } | |
1143 | |
1144 switch (changes[i][0]) { | |
1145 case KEYWORD_CHANGE_ADD: | |
15700
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1146 case KEYWORD_CHANGE_ADD_AND_FINAL: |
14584 | 1147 local_add[name_idx/32] |= 1U << (name_idx%32); |
1148 break; | |
1149 case KEYWORD_CHANGE_REMOVE: | |
1150 local_remove[name_idx/32] |= 1U << (name_idx%32); | |
1151 break; | |
1152 case KEYWORD_CHANGE_FINAL: | |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1153 break; |
14584 | 1154 } |
1155 } | |
1156 for (i = 0; local_keywords[i] != NULL; i++) { | |
1157 name = local_keywords[i]; | |
1158 if (!keyword_find(&all_keywords, name, &name_idx)) { | |
1159 name_idx = array_count(&all_keywords); | |
1160 array_append(&all_keywords, &name, 1); | |
1161 } | |
1162 local_final[name_idx/32] |= 1U << (name_idx%32); | |
1163 } | |
1164 i_assert(array_count(&all_keywords) <= array_size*32); | |
1165 array_size = (array_count(&all_keywords)+31) / 32; | |
1166 | |
1167 /* merge keywords */ | |
1168 for (i = 0; i < array_size; i++) { | |
1169 merge_flags(local_final[i], local_add[i], local_remove[i], | |
1170 remote_final[i], remote_add[i], remote_remove[i], | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1171 0, prefer_remote, prefer_remote, |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1172 &change_add[i], &change_remove[i], |
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1173 remote_changed, remote_pvt_changed); |
14584 | 1174 if (change_add[i] != 0) { |
1175 keywords_append(&add_keywords, &all_keywords, | |
1176 change_add[i], i*32); | |
1177 } | |
1178 if (change_remove[i] != 0) { | |
1179 keywords_append(&remove_keywords, &all_keywords, | |
15696
2801de211b78
dsync: Fixed syncing keyword removals.
Timo Sirainen <tss@iki.fi>
parents:
15694
diff
changeset
|
1180 change_remove[i], i*32); |
14584 | 1181 } |
1182 } | |
1183 | |
1184 /* apply changes */ | |
1185 if (array_count(&add_keywords) > 0) { | |
14686
9ff19c1d5f69
Added array_append_zero() to write a zero-filled record to an array.
Timo Sirainen <tss@iki.fi>
parents:
14682
diff
changeset
|
1186 array_append_zero(&add_keywords); |
14584 | 1187 kw = mailbox_keywords_create_valid(mail->box, |
1188 array_idx(&add_keywords, 0)); | |
1189 mail_update_keywords(mail, MODIFY_ADD, kw); | |
1190 mailbox_keywords_unref(&kw); | |
1191 } | |
1192 if (array_count(&remove_keywords) > 0) { | |
14686
9ff19c1d5f69
Added array_append_zero() to write a zero-filled record to an array.
Timo Sirainen <tss@iki.fi>
parents:
14682
diff
changeset
|
1193 array_append_zero(&remove_keywords); |
14584 | 1194 kw = mailbox_keywords_create_valid(mail->box, |
1195 array_idx(&remove_keywords, 0)); | |
1196 mail_update_keywords(mail, MODIFY_REMOVE, kw); | |
1197 mailbox_keywords_unref(&kw); | |
1198 } | |
1199 } | |
1200 | |
1201 static void | |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1202 dsync_mailbox_import_replace_flags(struct mail *mail, |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1203 const struct dsync_mail_change *change) |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1204 { |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1205 ARRAY_TYPE(const_string) keywords; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1206 struct mail_keywords *kw; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1207 const char *const *changes, *name; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1208 unsigned int i, count; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1209 |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1210 if (array_is_created(&change->keyword_changes)) |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1211 changes = array_get(&change->keyword_changes, &count); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1212 else { |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1213 changes = NULL; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1214 count = 0; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1215 } |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1216 t_array_init(&keywords, count+1); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1217 for (i = 0; i < count; i++) { |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1218 switch (changes[i][0]) { |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1219 case KEYWORD_CHANGE_ADD: |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1220 case KEYWORD_CHANGE_FINAL: |
15700
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
1221 case KEYWORD_CHANGE_ADD_AND_FINAL: |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1222 name = changes[i]+1; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1223 array_append(&keywords, &name, 1); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1224 break; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1225 case KEYWORD_CHANGE_REMOVE: |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1226 break; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1227 } |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1228 } |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1229 array_append_zero(&keywords); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1230 |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1231 kw = mailbox_keywords_create_valid(mail->box, array_idx(&keywords, 0)); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1232 mail_update_keywords(mail, MODIFY_REPLACE, kw); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1233 mailbox_keywords_unref(&kw); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1234 |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1235 mail_update_flags(mail, MODIFY_REPLACE, |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1236 change->add_flags | change->final_flags); |
15589
df5b25b11592
dsync: Avoid updating modseqs unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
15496
diff
changeset
|
1237 if (mail_get_modseq(mail) < change->modseq) |
df5b25b11592
dsync: Avoid updating modseqs unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
15496
diff
changeset
|
1238 mail_update_modseq(mail, change->modseq); |
df5b25b11592
dsync: Avoid updating modseqs unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
15496
diff
changeset
|
1239 if (mail_get_pvt_modseq(mail) < change->pvt_modseq) |
df5b25b11592
dsync: Avoid updating modseqs unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
15496
diff
changeset
|
1240 mail_update_pvt_modseq(mail, change->pvt_modseq); |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1241 } |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1242 |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1243 static void |
14584 | 1244 dsync_mailbox_import_flag_change(struct dsync_mailbox_importer *importer, |
1245 const struct dsync_mail_change *change) | |
1246 { | |
1247 const struct dsync_mail_change *local_change; | |
1248 enum mail_flags local_add, local_remove; | |
1249 uint32_t change_add, change_remove; | |
15698
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1250 uint64_t new_modseq; |
14584 | 1251 ARRAY_TYPE(const_string) local_keyword_changes = ARRAY_INIT; |
1252 struct mail *mail; | |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1253 bool prefer_remote, prefer_pvt_remote; |
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1254 bool remote_changed = FALSE, remote_pvt_changed = FALSE; |
14584 | 1255 |
1256 i_assert((change->add_flags & change->remove_flags) == 0); | |
1257 | |
1258 if (importer->cur_mail != NULL && | |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1259 importer->cur_mail->uid == change->uid) { |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1260 if (!dsync_check_cur_guid(importer, change)) |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1261 return; |
14584 | 1262 mail = importer->cur_mail; |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1263 } else { |
14584 | 1264 if (!dsync_import_set_mail(importer, change)) |
1265 return; | |
1266 mail = importer->mail; | |
1267 } | |
1268 | |
15257
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1269 if (importer->revert_local_changes) { |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1270 /* dsync backup: just make the local look like remote. */ |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1271 dsync_mailbox_import_replace_flags(mail, change); |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1272 return; |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1273 } |
60f0cb48fdb2
doveadm backup: Revert all local changes.
Timo Sirainen <tss@iki.fi>
parents:
15233
diff
changeset
|
1274 |
14923
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
1275 local_change = hash_table_lookup(importer->local_changes, |
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
1276 POINTER_CAST(change->uid)); |
14584 | 1277 if (local_change == NULL) { |
1278 local_add = local_remove = 0; | |
1279 } else { | |
1280 local_add = local_change->add_flags; | |
1281 local_remove = local_change->remove_flags; | |
1282 local_keyword_changes = local_change->keyword_changes; | |
1283 } | |
1284 | |
1285 if (mail_get_modseq(mail) < change->modseq) | |
1286 prefer_remote = TRUE; | |
1287 else if (mail_get_modseq(mail) > change->modseq) | |
1288 prefer_remote = FALSE; | |
1289 else { | |
1290 /* identical modseq, we'll just have to pick one. | |
1291 Note that both brains need to pick the same one, otherwise | |
1292 they become unsynced. */ | |
1293 prefer_remote = !importer->master_brain; | |
1294 } | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1295 if (mail_get_pvt_modseq(mail) < change->pvt_modseq) |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1296 prefer_pvt_remote = TRUE; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1297 else if (mail_get_pvt_modseq(mail) > change->pvt_modseq) |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1298 prefer_pvt_remote = FALSE; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1299 else |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1300 prefer_pvt_remote = !importer->master_brain; |
14584 | 1301 |
1302 /* merge flags */ | |
1303 merge_flags(mail_get_flags(mail), local_add, local_remove, | |
1304 change->final_flags, change->add_flags, change->remove_flags, | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1305 mailbox_get_private_flags_mask(mail->box), |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
1306 prefer_remote, prefer_pvt_remote, |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1307 &change_add, &change_remove, |
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1308 &remote_changed, &remote_pvt_changed); |
14584 | 1309 |
1310 if (change_add != 0) | |
1311 mail_update_flags(mail, MODIFY_ADD, change_add); | |
1312 if (change_remove != 0) | |
1313 mail_update_flags(mail, MODIFY_REMOVE, change_remove); | |
1314 | |
1315 /* merge keywords */ | |
1316 merge_keywords(mail, &local_keyword_changes, &change->keyword_changes, | |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1317 prefer_remote, &remote_changed, &remote_pvt_changed); |
15698
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1318 |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1319 /* update modseqs. try to anticipate when we have to increase modseq |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1320 to get it closer to what remote has (although we can't guess it |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1321 exactly correctly) */ |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1322 new_modseq = change->modseq; |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1323 if (remote_changed && new_modseq <= importer->remote_highest_modseq) |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1324 new_modseq = importer->remote_highest_modseq+1; |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1325 if (mail_get_modseq(mail) < new_modseq) |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1326 mail_update_modseq(mail, new_modseq); |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1327 |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1328 new_modseq = change->pvt_modseq; |
15702
85e464d088da
dsync: More fixes to merging flag/keyword changes.
Timo Sirainen <tss@iki.fi>
parents:
15700
diff
changeset
|
1329 if (remote_pvt_changed && new_modseq <= importer->remote_highest_pvt_modseq) |
15698
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1330 new_modseq = importer->remote_highest_pvt_modseq+1; |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1331 if (mail_get_pvt_modseq(mail) < new_modseq) |
798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
Timo Sirainen <tss@iki.fi>
parents:
15696
diff
changeset
|
1332 mail_update_pvt_modseq(mail, new_modseq); |
14584 | 1333 } |
1334 | |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1335 static bool |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1336 dsync_mail_change_have_keyword(const struct dsync_mail_change *change, |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1337 const char *keyword) |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1338 { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1339 const char *const *strp; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1340 |
18183
b505739970e7
dsync: Crashfix to -F parameter handling.
Timo Sirainen <tss@iki.fi>
parents:
18181
diff
changeset
|
1341 if (!array_is_created(&change->keyword_changes)) |
b505739970e7
dsync: Crashfix to -F parameter handling.
Timo Sirainen <tss@iki.fi>
parents:
18181
diff
changeset
|
1342 return FALSE; |
b505739970e7
dsync: Crashfix to -F parameter handling.
Timo Sirainen <tss@iki.fi>
parents:
18181
diff
changeset
|
1343 |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1344 array_foreach(&change->keyword_changes, strp) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1345 switch ((*strp)[0]) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1346 case KEYWORD_CHANGE_FINAL: |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1347 case KEYWORD_CHANGE_ADD_AND_FINAL: |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1348 if (strcasecmp((*strp)+1, keyword) == 0) |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1349 return TRUE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1350 break; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1351 default: |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1352 break; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1353 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1354 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1355 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1356 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1357 |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1358 static bool |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1359 dsync_mailbox_import_want_change(struct dsync_mailbox_importer *importer, |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1360 const struct dsync_mail_change *change, |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1361 const char **result_r) |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1362 { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1363 if (importer->sync_since_timestamp > 0) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1364 i_assert(change->received_timestamp > 0); |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1365 if (change->received_timestamp < importer->sync_since_timestamp) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1366 /* mail has too old timestamp - skip it */ |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1367 *result_r = "Ignoring missing local mail with too old timestamp"; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1368 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1369 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1370 } |
20831
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1371 if (importer->sync_until_timestamp > 0) { |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1372 i_assert(change->received_timestamp > 0); |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1373 if (change->received_timestamp > importer->sync_until_timestamp) { |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1374 /* mail has too new timestamp - skip it */ |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1375 *result_r = "Ignoring missing local mail with too new timestamp"; |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1376 return FALSE; |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1377 } |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1378 } |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1379 if (importer->sync_max_size > 0) { |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1380 i_assert(change->virtual_size != (uoff_t)-1); |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1381 if (change->virtual_size < importer->sync_max_size) { |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1382 /* mail is too large - skip it */ |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1383 *result_r = "Ignoring missing local mail with too large size"; |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1384 return FALSE; |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1385 } |
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1386 } |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1387 if (importer->sync_flag != 0) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1388 bool have_flag = (change->final_flags & importer->sync_flag) != 0; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1389 |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1390 if (have_flag && importer->sync_flag_dontwant) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1391 *result_r = "Ignoring missing local mail that doesn't have wanted flags"; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1392 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1393 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1394 if (!have_flag && !importer->sync_flag_dontwant) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1395 *result_r = "Ignoring missing local mail that has unwanted flags"; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1396 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1397 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1398 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1399 if (importer->sync_keyword != NULL) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1400 bool have_kw = dsync_mail_change_have_keyword(change, importer->sync_keyword); |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1401 |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1402 if (have_kw && importer->sync_flag_dontwant) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1403 *result_r = "Ignoring missing local mail that doesn't have wanted keywords"; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1404 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1405 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1406 if (!have_kw && !importer->sync_flag_dontwant) { |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1407 *result_r = "Ignoring missing local mail that has unwanted keywords"; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1408 return FALSE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1409 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1410 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1411 return TRUE; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1412 } |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1413 |
14584 | 1414 static void |
1415 dsync_mailbox_import_save(struct dsync_mailbox_importer *importer, | |
1416 const struct dsync_mail_change *change) | |
1417 { | |
1418 struct dsync_mail_change *save; | |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1419 const char *result; |
14584 | 1420 |
1421 i_assert(change->guid != NULL); | |
1422 | |
1423 if (change->uid == importer->last_common_uid) { | |
1424 /* we've already verified that the GUID matches. | |
1425 apply flag changes if there are any. */ | |
1426 i_assert(!importer->last_common_uid_found); | |
1427 dsync_mailbox_import_flag_change(importer, change); | |
1428 return; | |
1429 } | |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1430 if (!dsync_mailbox_import_want_change(importer, change, &result)) |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1431 return; |
14584 | 1432 |
1433 save = p_new(importer->pool, struct dsync_mail_change, 1); | |
1434 dsync_mail_change_dup(importer->pool, change, save); | |
1435 | |
1436 if (importer->last_common_uid_found) { | |
1437 /* this is a new mail. its UID may or may not conflict with | |
1438 an existing local mail, we'll figure it out later. */ | |
1439 i_assert(change->uid > importer->last_common_uid); | |
1440 dsync_mailbox_save(importer, save); | |
1441 } else { | |
1442 /* the local mail is expunged. we'll decide later if we want | |
1443 to save this mail locally or expunge it form remote. */ | |
1444 i_assert(change->uid > importer->last_common_uid); | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1445 i_assert(importer->cur_mail == NULL || |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1446 change->uid < importer->cur_mail->uid); |
14584 | 1447 array_append(&importer->maybe_saves, &save, 1); |
1448 } | |
1449 } | |
1450 | |
1451 static void | |
1452 dsync_mailbox_import_expunge(struct dsync_mailbox_importer *importer, | |
1453 const struct dsync_mail_change *change) | |
1454 { | |
1455 | |
1456 if (importer->last_common_uid_found) { | |
1457 /* expunge the message, unless its GUID unexpectedly doesn't | |
1458 match */ | |
1459 i_assert(change->uid <= importer->last_common_uid); | |
1460 if (dsync_import_set_mail(importer, change)) | |
1461 mail_expunge(importer->mail); | |
15591
a7be0c9a00df
dsync: Crashfix for handling expunges from end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15590
diff
changeset
|
1462 } else if (importer->cur_mail == NULL || |
a7be0c9a00df
dsync: Crashfix for handling expunges from end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15590
diff
changeset
|
1463 change->uid < importer->cur_mail->uid) { |
14584 | 1464 /* already expunged locally, we can ignore this. |
1465 uid=last_common_uid if we managed to verify from | |
1466 transaction log that the GUIDs match */ | |
1467 i_assert(change->uid >= importer->last_common_uid); | |
1468 } else if (change->uid == importer->last_common_uid) { | |
1469 /* already verified that the GUID matches */ | |
1470 i_assert(importer->cur_mail->uid == change->uid); | |
15657
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1471 if (dsync_check_cur_guid(importer, change)) |
f0dbe8fc8905
dsync: Verify messages' GUIDs better.
Timo Sirainen <tss@iki.fi>
parents:
15619
diff
changeset
|
1472 mail_expunge(importer->cur_mail); |
14584 | 1473 } else { |
1474 /* we don't know yet if we should expunge this | |
1475 message or not. queue it until we do. */ | |
1476 i_assert(change->uid > importer->last_common_uid); | |
14676
69ba6977bed8
seq_range_array_add() API changed. Added other functions to provide the less common use cases.
Timo Sirainen <tss@iki.fi>
parents:
14675
diff
changeset
|
1477 seq_range_array_add(&importer->maybe_expunge_uids, change->uid); |
14584 | 1478 } |
1479 } | |
1480 | |
1481 static void | |
1482 dsync_mailbox_rewind_search(struct dsync_mailbox_importer *importer) | |
1483 { | |
1484 /* If there are local mails after last_common_uid which we skipped | |
1485 while trying to match the next message, we need to now go back */ | |
1486 if (importer->cur_mail != NULL && | |
1487 importer->cur_mail->uid <= importer->last_common_uid+1) | |
1488 return; | |
1489 | |
1490 importer->cur_mail = NULL; | |
1491 importer->cur_guid = NULL; | |
15753
f58e7b386c6e
dsync: Fixes for syncing without GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15743
diff
changeset
|
1492 importer->cur_hdr_hash = NULL; |
14584 | 1493 importer->next_local_seq = 0; |
1494 | |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
1495 (void)mailbox_search_deinit(&importer->search_ctx); |
14584 | 1496 dsync_mailbox_import_search_init(importer); |
1497 } | |
1498 | |
1499 static void | |
1500 dsync_mailbox_common_uid_found(struct dsync_mailbox_importer *importer) | |
1501 { | |
1502 struct dsync_mail_change *const *saves; | |
1503 struct seq_range_iter iter; | |
1504 unsigned int n, i, count; | |
1505 uint32_t uid; | |
1506 | |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1507 if (importer->debug) T_BEGIN { |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1508 string_t *expunges = t_str_new(64); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1509 |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1510 imap_write_seq_range(expunges, &importer->maybe_expunge_uids); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1511 imp_debug(importer, "Last common UID=%u. Delayed expunges=%s", |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1512 importer->last_common_uid, str_c(expunges)); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1513 } T_END; |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
1514 |
14584 | 1515 importer->last_common_uid_found = TRUE; |
1516 dsync_mailbox_rewind_search(importer); | |
1517 | |
1518 /* expunge the messages whose expunge-decision we delayed previously */ | |
1519 seq_range_array_iter_init(&iter, &importer->maybe_expunge_uids); n = 0; | |
1520 while (seq_range_array_iter_nth(&iter, n++, &uid)) { | |
1521 if (uid > importer->last_common_uid) { | |
1522 /* we expunge messages only up to last_common_uid, | |
1523 ignore the rest */ | |
1524 break; | |
1525 } | |
1526 | |
1527 if (mail_set_uid(importer->mail, uid)) | |
1528 mail_expunge(importer->mail); | |
1529 } | |
1530 | |
1531 /* handle pending saves */ | |
1532 saves = array_get(&importer->maybe_saves, &count); | |
1533 for (i = 0; i < count; i++) { | |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1534 if (saves[i]->uid > importer->last_common_uid) { |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1535 imp_debug(importer, "Delayed save UID=%u: Save", |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1536 saves[i]->uid); |
14584 | 1537 dsync_mailbox_save(importer, saves[i]); |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1538 } else { |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1539 imp_debug(importer, "Delayed save UID=%u: Ignore", |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1540 saves[i]->uid); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1541 } |
14584 | 1542 } |
1543 } | |
1544 | |
1545 static int | |
1546 dsync_mailbox_import_match_msg(struct dsync_mailbox_importer *importer, | |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1547 const struct dsync_mail_change *change, |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1548 const char **result_r) |
14584 | 1549 { |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1550 const char *hdr_hash, *cmp_guid; |
14584 | 1551 |
1552 if (*change->guid != '\0' && *importer->cur_guid != '\0') { | |
1553 /* we have GUIDs, verify them */ | |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
1554 if (dsync_mail_change_guid_equals(importer, change, |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1555 importer->cur_guid, &cmp_guid)) { |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1556 *result_r = "GUIDs match"; |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
1557 return 1; |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1558 } else { |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1559 *result_r = t_strdup_printf("GUIDs don't match (%s vs %s)", |
17864 | 1560 importer->cur_guid, cmp_guid); |
15819
9c095a50ba3e
dsync: Improved unexpected error logging.
Timo Sirainen <tss@iki.fi>
parents:
15781
diff
changeset
|
1561 return 0; |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1562 } |
14584 | 1563 } |
1564 | |
1565 /* verify hdr_hash if it exists */ | |
1566 if (change->hdr_hash == NULL) { | |
1567 i_assert(*importer->cur_guid == '\0'); | |
16556
af8ce0a84bb5
dsync: Fixed handling expunges when GUIDs aren't supported by the backend(s).
Timo Sirainen <tss@iki.fi>
parents:
16539
diff
changeset
|
1568 if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { |
af8ce0a84bb5
dsync: Fixed handling expunges when GUIDs aren't supported by the backend(s).
Timo Sirainen <tss@iki.fi>
parents:
16539
diff
changeset
|
1569 /* the message was already expunged, so we don't know |
af8ce0a84bb5
dsync: Fixed handling expunges when GUIDs aren't supported by the backend(s).
Timo Sirainen <tss@iki.fi>
parents:
16539
diff
changeset
|
1570 its header. return "unknown". */ |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1571 *result_r = "Unknown match for expunge"; |
16556
af8ce0a84bb5
dsync: Fixed handling expunges when GUIDs aren't supported by the backend(s).
Timo Sirainen <tss@iki.fi>
parents:
16539
diff
changeset
|
1572 return -1; |
af8ce0a84bb5
dsync: Fixed handling expunges when GUIDs aren't supported by the backend(s).
Timo Sirainen <tss@iki.fi>
parents:
16539
diff
changeset
|
1573 } |
14584 | 1574 i_error("Mailbox %s: GUIDs not supported, " |
1575 "sync with header hashes instead", | |
1576 mailbox_get_vname(importer->box)); | |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
1577 importer->mail_error = MAIL_ERROR_TEMP; |
14584 | 1578 importer->failed = TRUE; |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1579 *result_r = "Error, invalid parameters"; |
14584 | 1580 return -1; |
1581 } | |
1582 | |
19646
25f06710e671
dsync: When comparing headers' hashes to match messages, try to normalize the input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1583 if (dsync_mail_get_hdr_hash(importer->cur_mail, |
22549
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
1584 importer->hdr_hash_version, |
400ff84f109d
dsync: Add hashed_headers setting
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22264
diff
changeset
|
1585 importer->hashed_headers, &hdr_hash) < 0) { |
14584 | 1586 dsync_mail_error(importer, importer->cur_mail, "hdr-stream"); |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1587 *result_r = "Error fetching header stream"; |
14584 | 1588 return -1; |
1589 } | |
20605
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1590 if (importer->empty_hdr_workaround && |
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1591 (dsync_mail_hdr_hash_is_empty(change->hdr_hash) || |
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1592 dsync_mail_hdr_hash_is_empty(hdr_hash))) { |
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1593 *result_r = "Empty headers found with workaround enabled - assuming a match"; |
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1594 return 1; |
b7616318f4d0
dsync: Fixed empty-header-workaround
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20595
diff
changeset
|
1595 } else if (strcmp(change->hdr_hash, hdr_hash) == 0) { |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1596 *result_r = "Headers hashes match"; |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1597 return 1; |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1598 } else { |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1599 *result_r = t_strdup_printf("Headers hashes don't match (%s vs %s)", |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1600 change->hdr_hash, hdr_hash); |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1601 return 0; |
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1602 } |
14584 | 1603 } |
1604 | |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1605 static bool |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1606 dsync_mailbox_find_common_expunged_uid(struct dsync_mailbox_importer *importer, |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1607 const struct dsync_mail_change *change, |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1608 const char **result_r) |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1609 { |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1610 const struct dsync_mail_change *local_change; |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1611 |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1612 if (*change->guid == '\0') { |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1613 /* remote doesn't support GUIDs, can't verify expunge */ |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1614 *result_r = "GUIDs not supported, can't verify expunge"; |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1615 return FALSE; |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1616 } |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1617 |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1618 /* local message is expunged. see if we can find its GUID from |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1619 transaction log and check if the GUIDs match. The GUID in |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1620 log is a 128bit GUID, so we may need to convert the remote's |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1621 GUID string to 128bit GUID first. */ |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1622 local_change = hash_table_lookup(importer->local_changes, |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1623 POINTER_CAST(change->uid)); |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1624 if (local_change == NULL || local_change->guid == NULL) { |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1625 *result_r = "Expunged local mail's GUID not found"; |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1626 return FALSE; |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1627 } |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1628 |
15667
1b18ff11effc
dsync: Fixes to handling storage formats that don't use 128bit GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
15664
diff
changeset
|
1629 i_assert(local_change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE); |
16977
8a7ecddca4ad
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
Timo Sirainen <tss@iki.fi>
parents:
16940
diff
changeset
|
1630 if (dsync_mail_change_guid_equals(importer, local_change, |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1631 change->guid, NULL)) { |
15779
4e90a6911b26
dsync: Fixed last-common-uid lookup when local UID was expunged but remote wasn't.
Timo Sirainen <tss@iki.fi>
parents:
15778
diff
changeset
|
1632 importer->last_common_uid = change->uid; |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1633 *result_r = "Expunged local mail's GUID matches remote"; |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1634 } else if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { |
15779
4e90a6911b26
dsync: Fixed last-common-uid lookup when local UID was expunged but remote wasn't.
Timo Sirainen <tss@iki.fi>
parents:
15778
diff
changeset
|
1635 dsync_mailbox_common_uid_found(importer); |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1636 *result_r = "Expunged local mail's GUID doesn't match remote GUID"; |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1637 } else { |
15694
1d88f01ba2aa
dsync: Ignore GUID mismatch on expunged message pair.
Timo Sirainen <tss@iki.fi>
parents:
15676
diff
changeset
|
1638 /* GUID mismatch for two expunged mails. dsync can't update |
1d88f01ba2aa
dsync: Ignore GUID mismatch on expunged message pair.
Timo Sirainen <tss@iki.fi>
parents:
15676
diff
changeset
|
1639 GUIDs for already expunged messages, so we can't immediately |
1d88f01ba2aa
dsync: Ignore GUID mismatch on expunged message pair.
Timo Sirainen <tss@iki.fi>
parents:
15676
diff
changeset
|
1640 determine that the rest of the messages are a mismatch. so |
1d88f01ba2aa
dsync: Ignore GUID mismatch on expunged message pair.
Timo Sirainen <tss@iki.fi>
parents:
15676
diff
changeset
|
1641 for now we'll just skip over this pair. */ |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1642 *result_r = "Expunged mails' GUIDs don't match - delaying decision"; |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1643 /* NOTE: the return value here doesn't matter, because the only |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1644 caller that checks for it never reaches this code path */ |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1645 } |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1646 return TRUE; |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1647 } |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1648 |
14584 | 1649 static void |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1650 dsync_mailbox_revert_missing(struct dsync_mailbox_importer *importer, |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1651 const struct dsync_mail_change *change) |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1652 { |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1653 i_assert(importer->revert_local_changes); |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1654 |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1655 /* mail exists on remote, but not locally. we'll need to |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1656 insert this mail back, which means deleting the whole |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1657 mailbox and resyncing. */ |
17886
d7ac3056ed7c
doveadm backup: When deleting a mailbox, log a warning, not just a debug message.
Timo Sirainen <tss@iki.fi>
parents:
17864
diff
changeset
|
1658 i_warning("Deleting mailbox '%s': UID=%u GUID=%s is missing locally", |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1659 mailbox_get_vname(importer->box), |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1660 change->uid, change->guid); |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1661 importer->delete_mailbox = TRUE; |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
1662 importer->mail_error = MAIL_ERROR_TEMP; |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1663 importer->failed = TRUE; |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1664 } |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1665 |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1666 static void |
14584 | 1667 dsync_mailbox_find_common_uid(struct dsync_mailbox_importer *importer, |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1668 const struct dsync_mail_change *change, |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1669 const char **result_r) |
14584 | 1670 { |
1671 int ret; | |
1672 | |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1673 i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE || |
20831
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1674 ((change->received_timestamp > 0 || |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1675 (importer->sync_since_timestamp == 0 && |
0c4e5c2725a3
doveadm-sync: Add end-date support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
20633
diff
changeset
|
1676 importer->sync_until_timestamp == 0)) && |
20633
d54651ba988a
doveadm sync/backup: Added -S <max size> parameter to skip too large mails.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20605
diff
changeset
|
1677 (change->virtual_size != (uoff_t)-1 || importer->sync_max_size == 0))); |
18177
f393f63764e0
dsync: Added -t <timestamp> parameter to save only mails newer than <timestamp>
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
1678 |
14584 | 1679 /* try to find the matching local mail */ |
1680 if (!importer_next_mail(importer, change->uid)) { | |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1681 /* no more local mails. we can still try to match |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1682 expunged mails though. */ |
15619
b27245a6adde
dsync: Another fix to handling expunges from the end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15618
diff
changeset
|
1683 if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { |
b27245a6adde
dsync: Another fix to handling expunges from the end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15618
diff
changeset
|
1684 /* mail doesn't exist remotely either, don't bother |
b27245a6adde
dsync: Another fix to handling expunges from the end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15618
diff
changeset
|
1685 looking it up locally. */ |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1686 *result_r = "Expunged mail not found locally"; |
15619
b27245a6adde
dsync: Another fix to handling expunges from the end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15618
diff
changeset
|
1687 return; |
b27245a6adde
dsync: Another fix to handling expunges from the end of mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15618
diff
changeset
|
1688 } |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1689 i_assert(change->guid != NULL); |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1690 if (!dsync_mailbox_import_want_change(importer, change, result_r)) |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1691 ; |
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1692 else if (importer->local_uid_next <= change->uid) { |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1693 dsync_mailbox_common_uid_found(importer); |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1694 *result_r = "Mail's UID is above local UIDNEXT"; |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1695 } else if (importer->revert_local_changes) { |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1696 dsync_mailbox_revert_missing(importer, change); |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1697 *result_r = "Reverting local change by deleting mailbox"; |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1698 } else if (!dsync_mailbox_find_common_expunged_uid(importer, change, result_r)) { |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1699 /* it's unknown if this mail existed locally and was |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1700 expunged. since we don't want to lose any mails, |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1701 assume that we need to preserve the mail. use the |
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1702 last message with a matching GUID as the last common |
15590
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1703 UID. */ |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1704 dsync_mailbox_common_uid_found(importer); |
ea3c1bd6d434
dsync: Fixed syncing expunge for last mail in mailbox.
Timo Sirainen <tss@iki.fi>
parents:
15589
diff
changeset
|
1705 } |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1706 *result_r = t_strdup_printf("%s - No more local mails found", *result_r); |
14584 | 1707 return; |
1708 } | |
1709 | |
1710 if (change->guid == NULL) { | |
1711 /* we can't know if this UID matches */ | |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1712 i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1713 *result_r = "Expunged mail has no GUID, can't verify it"; |
14584 | 1714 return; |
1715 } | |
1716 if (importer->cur_mail->uid == change->uid) { | |
1717 /* we have a matching local UID. check GUID to see if it's | |
1718 really the same mail or not */ | |
17862
c3ef6f19d518
dsync: Improved debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17861
diff
changeset
|
1719 if ((ret = dsync_mailbox_import_match_msg(importer, change, result_r)) < 0) { |
14584 | 1720 /* unknown */ |
1721 return; | |
1722 } | |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1723 if (ret > 0) { |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1724 importer->last_common_uid = change->uid; |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1725 } else if (!importer->revert_local_changes) { |
14584 | 1726 /* mismatch - found the first non-common UID */ |
1727 dsync_mailbox_common_uid_found(importer); | |
1728 } else { | |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1729 /* mismatch and we want to revert local changes - |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1730 need to delete the mailbox. */ |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1731 dsync_mailbox_revert_existing_uid(importer, change->uid, *result_r); |
14584 | 1732 } |
1733 return; | |
1734 } | |
18177
f393f63764e0
dsync: Added -t <timestamp> parameter to save only mails newer than <timestamp>
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
1735 /* mail exists remotely, but doesn't exist locally. */ |
18181
35e4a6ae8d85
dsync: Added -F parameter to sync only mails with[out] specific flag.
Timo Sirainen <tss@iki.fi>
parents:
18180
diff
changeset
|
1736 if (!dsync_mailbox_import_want_change(importer, change, result_r)) |
18177
f393f63764e0
dsync: Added -t <timestamp> parameter to save only mails newer than <timestamp>
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
1737 return; |
17888
68e5eaecc8b4
doveadm backup: Don't unnecessarily delete mailbox when handling expunges
Timo Sirainen <tss@iki.fi>
parents:
17887
diff
changeset
|
1738 if (importer->revert_local_changes && |
68e5eaecc8b4
doveadm backup: Don't unnecessarily delete mailbox when handling expunges
Timo Sirainen <tss@iki.fi>
parents:
17887
diff
changeset
|
1739 change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
1740 dsync_mailbox_revert_missing(importer, change); |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1741 *result_r = "Reverting local change by deleting mailbox"; |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1742 } else { |
17890
bf086c6f6e4a
dsync: Debug logging improvements and comment clarifications.
Timo Sirainen <tss@iki.fi>
parents:
17888
diff
changeset
|
1743 (void)dsync_mailbox_find_common_expunged_uid(importer, change, result_r); |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1744 } |
19228
83ccad730ea3
dsync: Removed unnecessary code - cur_mail is never NULL at this point.
Timo Sirainen <tss@iki.fi>
parents:
19084
diff
changeset
|
1745 *result_r = t_strdup_printf("%s (next local mail UID=%u)", |
20262
1f4e2c3a8512
dsync: Fixed potential crash
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20208
diff
changeset
|
1746 *result_r, importer->cur_mail == NULL ? 0 : importer->cur_mail->uid); |
14584 | 1747 } |
1748 | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1749 int dsync_mailbox_import_change(struct dsync_mailbox_importer *importer, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1750 const struct dsync_mail_change *change) |
14584 | 1751 { |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1752 const char *result; |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1753 |
14584 | 1754 i_assert(!importer->new_uids_assigned); |
1755 i_assert(importer->prev_uid < change->uid); | |
1756 | |
1757 importer->prev_uid = change->uid; | |
1758 | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1759 if (importer->failed) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1760 return -1; |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
1761 if (importer->require_full_resync) |
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
1762 return 0; |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1763 |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1764 if (!importer->last_common_uid_found) { |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1765 result = NULL; |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1766 dsync_mailbox_find_common_uid(importer, change, &result); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1767 i_assert(result != NULL); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1768 } else { |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1769 result = "New mail"; |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1770 } |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
1771 |
20208
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
1772 imp_debug(importer, "Import change type=%s GUID=%s UID=%u hdr_hash=%s result=%s", |
f1a5362b8a85
dsync: Debug logging improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20191
diff
changeset
|
1773 dsync_mail_change_type_names[change->type], |
17861
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1774 change->guid != NULL ? change->guid : "<unknown>", change->uid, |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1775 change->hdr_hash != NULL ? change->hdr_hash : "", result); |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1776 |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1777 if (importer->failed) |
0b4352d6dfdb
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
17860
diff
changeset
|
1778 return -1; |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
1779 if (importer->require_full_resync) |
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
1780 return 0; |
14584 | 1781 |
1782 if (importer->last_common_uid_found) { | |
1783 /* a) uid <= last_common_uid for flag changes and expunges. | |
1784 this happens only when last_common_uid was originally given | |
1785 as parameter to importer. | |
1786 | |
1787 when we're finding the last_common_uid ourself, | |
1788 uid>last_common_uid always in here, because | |
1789 last_common_uid_found=TRUE only after we find the first | |
1790 mismatch. | |
1791 | |
1792 b) uid > last_common_uid for i) new messages, ii) expunges | |
1793 that were sent "just in case" */ | |
1794 if (change->uid <= importer->last_common_uid) { | |
1795 i_assert(change->type != DSYNC_MAIL_CHANGE_TYPE_SAVE); | |
1796 } else if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { | |
1797 /* ignore */ | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1798 return 0; |
14584 | 1799 } else { |
1800 i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_SAVE); | |
1801 } | |
1802 } else { | |
1803 /* a) uid < last_common_uid can never happen */ | |
1804 i_assert(change->uid >= importer->last_common_uid); | |
1805 /* b) uid = last_common_uid if we've verified that the | |
1806 messages' GUIDs match so far. | |
1807 | |
1808 c) uid > last_common_uid: i) TYPE_EXPUNGE change has | |
1809 GUID=NULL, so we couldn't verify yet if it matches our | |
1810 local message, ii) local message is expunged and we couldn't | |
1811 find its GUID */ | |
1812 if (change->uid > importer->last_common_uid) { | |
1813 i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE || | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1814 importer->cur_mail == NULL || |
14584 | 1815 change->uid < importer->cur_mail->uid); |
1816 } | |
1817 } | |
1818 | |
1819 switch (change->type) { | |
1820 case DSYNC_MAIL_CHANGE_TYPE_SAVE: | |
1821 dsync_mailbox_import_save(importer, change); | |
1822 break; | |
1823 case DSYNC_MAIL_CHANGE_TYPE_EXPUNGE: | |
1824 dsync_mailbox_import_expunge(importer, change); | |
1825 break; | |
1826 case DSYNC_MAIL_CHANGE_TYPE_FLAG_CHANGE: | |
1827 i_assert(importer->last_common_uid_found); | |
1828 dsync_mailbox_import_flag_change(importer, change); | |
1829 break; | |
1830 } | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1831 return importer->failed ? -1 : 0; |
14584 | 1832 } |
1833 | |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1834 static int |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1835 importer_new_mail_final_uid_cmp(struct importer_new_mail *const *newmail1, |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1836 struct importer_new_mail *const *newmail2) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1837 { |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1838 if ((*newmail1)->final_uid < (*newmail2)->final_uid) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1839 return -1; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1840 if ((*newmail1)->final_uid > (*newmail2)->final_uid) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1841 return 1; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1842 return 0; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1843 } |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1844 |
14584 | 1845 static void |
1846 dsync_mailbox_import_assign_new_uids(struct dsync_mailbox_importer *importer) | |
1847 { | |
1848 struct importer_new_mail *newmail, *const *newmailp; | |
1849 uint32_t common_uid_next, new_uid; | |
1850 | |
1851 common_uid_next = I_MAX(importer->local_uid_next, | |
1852 importer->remote_uid_next); | |
1853 array_foreach_modifiable(&importer->newmails, newmailp) { | |
1854 newmail = *newmailp; | |
1855 if (newmail->skip) { | |
1856 /* already assigned */ | |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1857 i_assert(newmail->final_uid != 0); |
14584 | 1858 continue; |
1859 } | |
1860 | |
1861 /* figure out what UID to use for the mail */ | |
1862 if (newmail->uid_is_usable) { | |
1863 /* keep the UID */ | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1864 new_uid = newmail->final_uid; |
14584 | 1865 } else if (newmail->link != NULL && |
15618 | 1866 newmail->link->uid_is_usable) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1867 /* we can use the linked message's UID and expunge |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1868 this mail */ |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1869 new_uid = newmail->link->final_uid; |
15618 | 1870 } else { |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
1871 i_assert(!importer->revert_local_changes); |
14584 | 1872 new_uid = common_uid_next++; |
18178
dbf3a0701810
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
18177
diff
changeset
|
1873 imp_debug(importer, "UID %u isn't usable, assigning new UID %u", |
dbf3a0701810
dsync: Added more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
18177
diff
changeset
|
1874 newmail->final_uid, new_uid); |
15618 | 1875 } |
14584 | 1876 |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1877 newmail->final_uid = new_uid; |
15778
e49424a3b13e
dsync: Assert-crashfix for previous importer changes.
Timo Sirainen <tss@iki.fi>
parents:
15772
diff
changeset
|
1878 if (newmail->link != NULL && newmail->link != newmail) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1879 /* skip processing the linked mail */ |
14584 | 1880 newmail->link->skip = TRUE; |
1881 } | |
1882 } | |
15232
6c850258002f
doveadm sync/backup: Added -s <state> parameter to do a fast stateful sync.
Timo Sirainen <tss@iki.fi>
parents:
14926
diff
changeset
|
1883 importer->last_common_uid = common_uid_next-1; |
14584 | 1884 importer->new_uids_assigned = TRUE; |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1885 /* Sort the newmails by their final_uid. This is used for tracking |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1886 whether an intermediate commit is allowed. */ |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1887 array_sort(&importer->newmails, importer_new_mail_final_uid_cmp); |
14584 | 1888 } |
1889 | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1890 static int |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1891 dsync_mailbox_import_local_uid(struct dsync_mailbox_importer *importer, |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
1892 struct mail *mail, uint32_t uid, const char *guid, |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1893 struct dsync_mail *dmail_r) |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1894 { |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1895 const char *error_field, *errstr; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1896 enum mail_error error; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1897 |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
1898 if (!mail_set_uid(mail, uid)) |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1899 return 0; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1900 |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
1901 /* NOTE: Errors are logged, but they don't cause the entire import |
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
1902 to fail. */ |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
1903 if (dsync_mail_fill(mail, TRUE, dmail_r, &error_field) < 0) { |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
1904 errstr = mailbox_get_last_internal_error(mail->box, &error); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1905 if (error == MAIL_ERROR_EXPUNGED) |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1906 return 0; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1907 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1908 i_error("Mailbox %s: Can't lookup %s for UID=%u: %s", |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1909 mailbox_get_vname(importer->box), |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1910 error_field, uid, errstr); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1911 return -1; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1912 } |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1913 if (*guid != '\0' && strcmp(guid, dmail_r->guid) != 0) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1914 dsync_import_unexpected_state(importer, t_strdup_printf( |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1915 "Unexpected GUID mismatch (3) for UID=%u: %s != %s", |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1916 uid, dmail_r->guid, guid)); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1917 return -1; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1918 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1919 return 1; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1920 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1921 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1922 static void |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
1923 dsync_mailbox_import_saved_uid(struct dsync_mailbox_importer *importer, |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
1924 uint32_t uid) |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1925 { |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
1926 i_assert(importer->search_ctx == NULL); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
1927 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1928 if (importer->highest_wanted_uid < uid) |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1929 importer->highest_wanted_uid = uid; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1930 array_append(&importer->wanted_uids, &uid, 1); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1931 } |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
1932 |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1933 static void |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1934 dsync_mailbox_import_update_first_saved(struct dsync_mailbox_importer *importer) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1935 { |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1936 struct importer_new_mail *const *newmails; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1937 unsigned int count; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1938 |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1939 newmails = array_get(&importer->newmails, &count); |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1940 while (importer->first_unsaved_idx < count) { |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1941 if (!newmails[importer->first_unsaved_idx]->saved) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1942 break; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1943 importer->first_unsaved_idx++; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1944 } |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1945 } |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1946 |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1947 static void |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1948 dsync_mailbox_import_saved_newmail(struct dsync_mailbox_importer *importer, |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1949 struct importer_new_mail *newmail) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1950 { |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1951 dsync_mailbox_import_saved_uid(importer, newmail->final_uid); |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1952 newmail->saved = TRUE; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1953 |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1954 dsync_mailbox_import_update_first_saved(importer); |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1955 importer->saves_since_commit++; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1956 /* we can commit only if all the upcoming mails will have UIDs that |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1957 are larger than we're committing. |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1958 |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1959 Note that if any existing UIDs have been changed, the new UID is |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1960 usually higher than anything that is being saved so we can't do |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1961 an intermediate commit. It's too much extra work to try to handle |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1962 that situation. So here this never happens, because then |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1963 array_count(wanted_uids) is always higher than first_unsaved_idx. */ |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1964 if (importer->saves_since_commit >= importer->commit_msgs_interval && |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1965 importer->first_unsaved_idx == array_count(&importer->wanted_uids)) { |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1966 if (dsync_mailbox_import_commit(importer, FALSE) < 0) |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1967 importer->failed = TRUE; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1968 importer->saves_since_commit = 0; |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1969 } |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1970 } |
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
1971 |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1972 static bool |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1973 dsync_msg_change_uid(struct dsync_mailbox_importer *importer, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1974 uint32_t old_uid, uint32_t new_uid) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1975 { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1976 struct mail_save_context *save_ctx; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1977 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1978 IMPORTER_DEBUG_CHANGE(importer); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1979 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1980 if (!mail_set_uid(importer->mail, old_uid)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1981 return FALSE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1982 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1983 save_ctx = mailbox_save_alloc(importer->ext_trans); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1984 mailbox_save_copy_flags(save_ctx, importer->mail); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1985 mailbox_save_set_uid(save_ctx, new_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1986 if (mailbox_move(&save_ctx, importer->mail) < 0) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1987 return FALSE; |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
1988 dsync_mailbox_import_saved_uid(importer, new_uid); |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1989 return TRUE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1990 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1991 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1992 static bool |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1993 dsync_mailbox_import_change_uid(struct dsync_mailbox_importer *importer, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1994 ARRAY_TYPE(seq_range) *unwanted_uids, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1995 uint32_t wanted_uid) |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
1996 { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
1997 const struct seq_range *range; |
15820
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
1998 unsigned int count, n; |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
1999 struct seq_range_iter iter; |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2000 uint32_t uid; |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2001 |
15820
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2002 /* optimize by first trying to use the latest UID */ |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2003 range = array_get(unwanted_uids, &count); |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2004 if (count == 0) |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2005 return FALSE; |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2006 if (dsync_msg_change_uid(importer, range[count-1].seq2, wanted_uid)) { |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2007 seq_range_array_remove(unwanted_uids, range[count-1].seq2); |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2008 return TRUE; |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2009 } |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2010 if (mailbox_get_last_mail_error(importer->box) == MAIL_ERROR_EXPUNGED) |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2011 seq_range_array_remove(unwanted_uids, range[count-1].seq2); |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2012 |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2013 /* now try to use any of them by iterating through them. (would be |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2014 easier&faster to just iterate backwards, but probably too much |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2015 trouble to add such API) */ |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2016 n = 0; seq_range_array_iter_init(&iter, unwanted_uids); |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2017 while (seq_range_array_iter_nth(&iter, n++, &uid)) { |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2018 if (dsync_msg_change_uid(importer, uid, wanted_uid)) { |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2019 seq_range_array_remove(unwanted_uids, uid); |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2020 return TRUE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2021 } |
15820
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2022 if (mailbox_get_last_mail_error(importer->box) == MAIL_ERROR_EXPUNGED) |
e7396c0f7f66
dsync: Fixed infinite loop in importer.
Timo Sirainen <tss@iki.fi>
parents:
15819
diff
changeset
|
2023 seq_range_array_remove(unwanted_uids, uid); |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2024 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2025 return FALSE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2026 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2027 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2028 static bool |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2029 dsync_mailbox_import_try_local(struct dsync_mailbox_importer *importer, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2030 struct importer_new_mail *all_newmails, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2031 ARRAY_TYPE(seq_range) *local_uids, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2032 ARRAY_TYPE(seq_range) *wanted_uids) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2033 { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2034 ARRAY_TYPE(seq_range) assigned_uids, unwanted_uids; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2035 struct seq_range_iter local_iter, wanted_iter; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2036 unsigned int local_n, wanted_n; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2037 uint32_t local_uid, wanted_uid; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2038 struct importer_new_mail *mail; |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2039 struct dsync_mail dmail; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2040 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2041 if (array_count(local_uids) == 0) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2042 return FALSE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2043 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2044 local_n = wanted_n = 0; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2045 seq_range_array_iter_init(&local_iter, local_uids); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2046 seq_range_array_iter_init(&wanted_iter, wanted_uids); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2047 |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2048 /* wanted_uids contains UIDs that need to exist at the end. those that |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2049 don't already exist in local_uids have a higher UID than any |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2050 existing local UID */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2051 t_array_init(&assigned_uids, array_count(wanted_uids)); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2052 t_array_init(&unwanted_uids, 8); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2053 while (seq_range_array_iter_nth(&local_iter, local_n++, &local_uid)) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2054 if (seq_range_array_iter_nth(&wanted_iter, wanted_n, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2055 &wanted_uid)) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2056 if (local_uid == wanted_uid) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2057 /* we have exactly the UID we want. keep it. */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2058 seq_range_array_add(&assigned_uids, wanted_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2059 wanted_n++; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2060 continue; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2061 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2062 i_assert(local_uid < wanted_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2063 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2064 /* we no longer want this local UID. */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2065 seq_range_array_add(&unwanted_uids, local_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2066 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2067 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2068 /* reuse as many existing messages as possible by changing their UIDs */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2069 while (seq_range_array_iter_nth(&wanted_iter, wanted_n, &wanted_uid)) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2070 if (!dsync_mailbox_import_change_uid(importer, &unwanted_uids, |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2071 wanted_uid)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2072 break; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2073 seq_range_array_add(&assigned_uids, wanted_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2074 wanted_n++; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2075 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2076 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2077 /* expunge all unwanted messages */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2078 local_n = 0; seq_range_array_iter_init(&local_iter, &unwanted_uids); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2079 while (seq_range_array_iter_nth(&local_iter, local_n++, &local_uid)) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2080 IMPORTER_DEBUG_CHANGE(importer); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2081 if (mail_set_uid(importer->mail, local_uid)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2082 mail_expunge(importer->mail); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2083 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2084 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2085 /* mark mails whose UIDs we got to be skipped over later */ |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2086 for (mail = all_newmails; mail != NULL; mail = mail->next) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2087 if (!mail->skip && |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2088 seq_range_exists(&assigned_uids, mail->final_uid)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2089 mail->skip = TRUE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2090 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2091 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2092 if (!seq_range_array_iter_nth(&wanted_iter, wanted_n, &wanted_uid)) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2093 /* we've assigned all wanted UIDs */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2094 return TRUE; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2095 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2096 |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2097 /* try to find one existing message that we can use to copy to the |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2098 other instances */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2099 local_n = 0; seq_range_array_iter_init(&local_iter, local_uids); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2100 while (seq_range_array_iter_nth(&local_iter, local_n++, &local_uid)) { |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2101 if (dsync_mailbox_import_local_uid(importer, importer->mail, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2102 local_uid, all_newmails->guid, |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2103 &dmail) > 0) { |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2104 if (dsync_mailbox_save_newmails(importer, &dmail, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2105 all_newmails, FALSE)) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2106 return TRUE; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2107 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2108 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2109 return FALSE; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2110 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2111 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2112 static bool |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2113 dsync_mailbox_import_try_virtual_all(struct dsync_mailbox_importer *importer, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2114 struct importer_new_mail *all_newmails) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2115 { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2116 struct dsync_mail dmail; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2117 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2118 if (all_newmails->virtual_all_uid == 0) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2119 return FALSE; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2120 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2121 if (dsync_mailbox_import_local_uid(importer, importer->virtual_mail, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2122 all_newmails->virtual_all_uid, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2123 all_newmails->guid, &dmail) > 0) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2124 if (dsync_mailbox_save_newmails(importer, &dmail, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2125 all_newmails, FALSE)) |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2126 return TRUE; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2127 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2128 return FALSE; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2129 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2130 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2131 static bool |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2132 dsync_mailbox_import_handle_mail(struct dsync_mailbox_importer *importer, |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2133 struct importer_new_mail *all_newmails) |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2134 { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2135 ARRAY_TYPE(seq_range) local_uids, wanted_uids; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2136 struct dsync_mail_request *request; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2137 struct importer_new_mail *mail; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2138 const char *request_guid = NULL; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2139 uint32_t request_uid = 0; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2140 |
16206 | 2141 i_assert(all_newmails != NULL); |
2142 | |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2143 /* get the list of the current local UIDs and the wanted UIDs. |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2144 find the first remote instance that we can request in case there are |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2145 no local instances */ |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2146 t_array_init(&local_uids, 8); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2147 t_array_init(&wanted_uids, 8); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2148 for (mail = all_newmails; mail != NULL; mail = mail->next) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2149 if (mail->uid_in_local) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2150 seq_range_array_add(&local_uids, mail->local_uid); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2151 else if (request_guid == NULL) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2152 if (*mail->guid != '\0') |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2153 request_guid = mail->guid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2154 request_uid = mail->remote_uid; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2155 i_assert(request_uid != 0); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2156 } |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2157 if (!mail->skip) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2158 seq_range_array_add(&wanted_uids, mail->final_uid); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2159 } |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2160 i_assert(array_count(&wanted_uids) > 0); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2161 |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2162 if (!dsync_mailbox_import_try_local(importer, all_newmails, |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2163 &local_uids, &wanted_uids) && |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2164 !dsync_mailbox_import_try_virtual_all(importer, all_newmails)) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2165 /* no local instance. request from remote */ |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2166 IMPORTER_DEBUG_CHANGE(importer); |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2167 if (importer->want_mail_requests) { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2168 request = array_append_space(&importer->mail_requests); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2169 request->guid = request_guid; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2170 request->uid = request_uid; |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2171 } |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2172 return FALSE; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2173 } |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2174 /* successfully handled all the mails locally */ |
16539
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2175 importer->import_pos++; |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2176 return TRUE; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2177 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2178 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2179 static void |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2180 dsync_mailbox_import_find_virtual_uids(struct dsync_mailbox_importer *importer) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2181 { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2182 struct mail_search_context *search_ctx; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2183 struct mail_search_args *search_args; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2184 struct importer_new_mail *newmail; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2185 struct mail *mail; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2186 const char *guid; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2187 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2188 if (mailbox_sync(importer->virtual_all_box, 0) < 0) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2189 i_error("Couldn't sync \\All mailbox '%s': %s", |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2190 mailbox_get_vname(importer->virtual_all_box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2191 mailbox_get_last_internal_error(importer->virtual_all_box, NULL)); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2192 return; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2193 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2194 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2195 search_args = mail_search_build_init(); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2196 mail_search_build_add_all(search_args); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2197 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2198 importer->virtual_trans = |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2199 mailbox_transaction_begin(importer->virtual_all_box, |
19318
f9a143c630a5
dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
19228
diff
changeset
|
2200 importer->transaction_flags); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2201 search_ctx = mailbox_search_init(importer->virtual_trans, search_args, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2202 NULL, MAIL_FETCH_GUID, NULL); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2203 mail_search_args_unref(&search_args); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2204 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2205 while (mailbox_search_next(search_ctx, &mail)) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2206 if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) < 0) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2207 /* ignore errors */ |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2208 continue; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2209 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2210 newmail = hash_table_lookup(importer->import_guids, guid); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2211 if (newmail != NULL && newmail->virtual_all_uid == 0) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2212 newmail->virtual_all_uid = mail->uid; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2213 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2214 if (mailbox_search_deinit(&search_ctx) < 0) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2215 i_error("Couldn't search \\All mailbox '%s': %s", |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2216 mailbox_get_vname(importer->virtual_all_box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2217 mailbox_get_last_internal_error(importer->virtual_all_box, NULL)); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2218 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2219 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2220 importer->virtual_mail = mail_alloc(importer->virtual_trans, 0, NULL); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2221 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2222 |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2223 static void |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2224 dsync_mailbox_import_handle_local_mails(struct dsync_mailbox_importer *importer) |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2225 { |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2226 struct hash_iterate_context *iter; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2227 const char *key; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2228 void *key2; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2229 struct importer_new_mail *mail; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2230 |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2231 if (importer->virtual_all_box != NULL && |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2232 hash_table_count(importer->import_guids) > 0) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2233 /* find UIDs in \All mailbox for all wanted GUIDs. */ |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2234 dsync_mailbox_import_find_virtual_uids(importer); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2235 } |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2236 |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2237 iter = hash_table_iterate_init(importer->import_guids); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2238 while (hash_table_iterate(iter, importer->import_guids, &key, &mail)) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2239 T_BEGIN { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2240 if (dsync_mailbox_import_handle_mail(importer, mail)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2241 hash_table_remove(importer->import_guids, key); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2242 } T_END; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2243 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2244 hash_table_iterate_deinit(&iter); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2245 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2246 iter = hash_table_iterate_init(importer->import_uids); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2247 while (hash_table_iterate(iter, importer->import_uids, &key2, &mail)) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2248 T_BEGIN { |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2249 if (dsync_mailbox_import_handle_mail(importer, mail)) |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2250 hash_table_remove(importer->import_uids, key2); |
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2251 } T_END; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2252 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2253 hash_table_iterate_deinit(&iter); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2254 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2255 |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
2256 int dsync_mailbox_import_changes_finish(struct dsync_mailbox_importer *importer) |
14584 | 2257 { |
2258 i_assert(!importer->new_uids_assigned); | |
2259 | |
2260 if (!importer->last_common_uid_found) { | |
2261 /* handle pending expunges and flag updates */ | |
2262 dsync_mailbox_common_uid_found(importer); | |
2263 } | |
2264 /* skip common local mails */ | |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
2265 (void)importer_next_mail(importer, importer->last_common_uid+1); |
14584 | 2266 /* if there are any local mails left, add them to newmails list */ |
17518
25326be366c5
dsync: Fixed infinite looping on error condition.
Timo Sirainen <tss@iki.fi>
parents:
17464
diff
changeset
|
2267 while (importer->cur_mail != NULL && !importer->failed) |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
2268 (void)dsync_mailbox_try_save(importer, NULL); |
14584 | 2269 |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2270 if (importer->search_ctx != NULL) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2271 if (mailbox_search_deinit(&importer->search_ctx) < 0) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2272 i_error("Mailbox %s: Search failed: %s", |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2273 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2274 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2275 &importer->mail_error)); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2276 importer->failed = TRUE; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2277 } |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2278 } |
16539
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2279 importer->import_count = hash_table_count(importer->import_guids) + |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2280 hash_table_count(importer->import_uids); |
16256
194df093a05f
dsync: Fixed assert-crash caused by previous change
Timo Sirainen <tss@iki.fi>
parents:
16255
diff
changeset
|
2281 |
194df093a05f
dsync: Fixed assert-crash caused by previous change
Timo Sirainen <tss@iki.fi>
parents:
16255
diff
changeset
|
2282 dsync_mailbox_import_assign_new_uids(importer); |
194df093a05f
dsync: Fixed assert-crash caused by previous change
Timo Sirainen <tss@iki.fi>
parents:
16255
diff
changeset
|
2283 /* save mails from local sources where possible, |
194df093a05f
dsync: Fixed assert-crash caused by previous change
Timo Sirainen <tss@iki.fi>
parents:
16255
diff
changeset
|
2284 request the rest from remote */ |
19660
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
2285 if (!importer->failed) |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
2286 dsync_mailbox_import_handle_local_mails(importer); |
7a3a138a4986
doveadm backup: Detect and handle conflicts earlier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19646
diff
changeset
|
2287 return importer->failed ? -1 : 0; |
14584 | 2288 } |
2289 | |
2290 const struct dsync_mail_request * | |
2291 dsync_mailbox_import_next_request(struct dsync_mailbox_importer *importer) | |
2292 { | |
2293 const struct dsync_mail_request *requests; | |
2294 unsigned int count; | |
2295 | |
2296 requests = array_get(&importer->mail_requests, &count); | |
2297 if (importer->mail_request_idx == count) | |
2298 return NULL; | |
2299 return &requests[importer->mail_request_idx++]; | |
2300 } | |
2301 | |
2302 static const char *const * | |
2303 dsync_mailbox_get_final_keywords(const struct dsync_mail_change *change) | |
2304 { | |
2305 ARRAY_TYPE(const_string) keywords; | |
2306 const char *const *changes; | |
2307 unsigned int i, count; | |
2308 | |
2309 if (!array_is_created(&change->keyword_changes)) | |
2310 return NULL; | |
2311 | |
2312 changes = array_get(&change->keyword_changes, &count); | |
2313 t_array_init(&keywords, count); | |
2314 for (i = 0; i < count; i++) { | |
2315 if (changes[i][0] == KEYWORD_CHANGE_ADD || | |
15700
067179cbabc2
dsync: Fixed syncing message keywords.
Timo Sirainen <tss@iki.fi>
parents:
15699
diff
changeset
|
2316 changes[i][0] == KEYWORD_CHANGE_ADD_AND_FINAL) { |
14584 | 2317 const char *name = changes[i]+1; |
2318 | |
2319 array_append(&keywords, &name, 1); | |
2320 } | |
2321 } | |
2322 if (array_count(&keywords) == 0) | |
2323 return NULL; | |
2324 | |
14686
9ff19c1d5f69
Added array_append_zero() to write a zero-filled record to an array.
Timo Sirainen <tss@iki.fi>
parents:
14682
diff
changeset
|
2325 array_append_zero(&keywords); |
14584 | 2326 return array_idx(&keywords, 0); |
2327 } | |
2328 | |
2329 static void | |
2330 dsync_mailbox_save_set_metadata(struct dsync_mailbox_importer *importer, | |
2331 struct mail_save_context *save_ctx, | |
2332 const struct dsync_mail_change *change) | |
2333 { | |
2334 const char *const *keyword_names; | |
2335 struct mail_keywords *keywords; | |
2336 | |
2337 keyword_names = dsync_mailbox_get_final_keywords(change); | |
2338 keywords = keyword_names == NULL ? NULL : | |
2339 mailbox_keywords_create_valid(importer->box, | |
2340 keyword_names); | |
2341 mailbox_save_set_flags(save_ctx, change->final_flags, keywords); | |
2342 if (keywords != NULL) | |
2343 mailbox_keywords_unref(&keywords); | |
2344 | |
2345 if (change->modseq > 1) { | |
2346 (void)mailbox_enable(importer->box, MAILBOX_FEATURE_CONDSTORE); | |
2347 mailbox_save_set_min_modseq(save_ctx, change->modseq); | |
2348 } | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2349 /* FIXME: if there already are private flags, they get lost because |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2350 saving can't handle updating private index. they get added on the |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2351 next sync though. if this is fixed here, set min_pvt_modseq also. */ |
14584 | 2352 } |
2353 | |
2354 static int | |
2355 dsync_msg_try_copy(struct dsync_mailbox_importer *importer, | |
2356 struct mail_save_context **save_ctx_p, | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2357 struct importer_new_mail **all_newmails_forcopy) |
14584 | 2358 { |
2359 struct importer_new_mail *inst; | |
2360 | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2361 for (inst = *all_newmails_forcopy; inst != NULL; inst = inst->next) { |
14584 | 2362 if (inst->uid_in_local && !inst->copy_failed && |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2363 mail_set_uid(importer->mail, inst->local_uid)) { |
14584 | 2364 if (mailbox_copy(save_ctx_p, importer->mail) < 0) { |
2365 inst->copy_failed = TRUE; | |
2366 return -1; | |
2367 } | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2368 *all_newmails_forcopy = inst; |
14584 | 2369 return 1; |
2370 } | |
2371 } | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2372 *all_newmails_forcopy = NULL; |
14584 | 2373 return 0; |
2374 } | |
2375 | |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2376 static void |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2377 dsync_mailbox_save_set_nonminimal(struct mail_save_context *save_ctx, |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2378 const struct dsync_mail *mail) |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2379 { |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2380 if (mail->pop3_uidl != NULL && *mail->pop3_uidl != '\0') |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2381 mailbox_save_set_pop3_uidl(save_ctx, mail->pop3_uidl); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2382 if (mail->pop3_order > 0) |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2383 mailbox_save_set_pop3_order(save_ctx, mail->pop3_order); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2384 mailbox_save_set_received_date(save_ctx, mail->received_date, 0); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2385 } |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2386 |
14584 | 2387 static struct mail_save_context * |
2388 dsync_mailbox_save_init(struct dsync_mailbox_importer *importer, | |
2389 const struct dsync_mail *mail, | |
2390 struct importer_new_mail *newmail) | |
2391 { | |
2392 struct mail_save_context *save_ctx; | |
2393 | |
2394 save_ctx = mailbox_save_alloc(importer->ext_trans); | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2395 mailbox_save_set_uid(save_ctx, newmail->final_uid); |
14584 | 2396 if (*mail->guid != '\0') |
2397 mailbox_save_set_guid(save_ctx, mail->guid); | |
17296
99a4788770cb
dsync: saved-date doesn't need to be looked up until mail body is being read.
Timo Sirainen <tss@iki.fi>
parents:
17282
diff
changeset
|
2398 if (mail->saved_date != 0) |
99a4788770cb
dsync: saved-date doesn't need to be looked up until mail body is being read.
Timo Sirainen <tss@iki.fi>
parents:
17282
diff
changeset
|
2399 mailbox_save_set_save_date(save_ctx, mail->saved_date); |
14584 | 2400 dsync_mailbox_save_set_metadata(importer, save_ctx, newmail->change); |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2401 |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2402 if (!mail->minimal_fields) |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2403 dsync_mailbox_save_set_nonminimal(save_ctx, mail); |
14584 | 2404 return save_ctx; |
2405 } | |
2406 | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2407 static bool |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2408 dsync_mailbox_save_body(struct dsync_mailbox_importer *importer, |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2409 const struct dsync_mail *mail, |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2410 struct importer_new_mail *newmail, |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2411 struct importer_new_mail **all_newmails_forcopy, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2412 bool remote_mail) |
14584 | 2413 { |
2414 struct mail_save_context *save_ctx; | |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2415 struct istream *input; |
14584 | 2416 ssize_t ret; |
2417 bool save_failed = FALSE; | |
2418 | |
2419 /* try to save the mail by copying an existing mail */ | |
2420 save_ctx = dsync_mailbox_save_init(importer, mail, newmail); | |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2421 if ((ret = dsync_msg_try_copy(importer, &save_ctx, all_newmails_forcopy)) < 0) { |
14584 | 2422 if (save_ctx == NULL) |
2423 save_ctx = dsync_mailbox_save_init(importer, mail, newmail); | |
2424 } | |
15676
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2425 if (ret <= 0 && mail->input_mail != NULL) { |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2426 /* copy using the source mail */ |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2427 i_assert(mail->input_mail->uid == mail->input_mail_uid); |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2428 if (mailbox_copy(&save_ctx, mail->input_mail) == 0) |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2429 ret = 1; |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2430 else { |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2431 ret = -1; |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2432 save_ctx = dsync_mailbox_save_init(importer, mail, newmail); |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2433 } |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2434 |
d3cda5a567be
dsync: When syncing locally, mailbox_copy() the mail to attempt a fast copy.
Timo Sirainen <tss@iki.fi>
parents:
15668
diff
changeset
|
2435 } |
14584 | 2436 if (ret > 0) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2437 i_assert(save_ctx == NULL); |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
2438 dsync_mailbox_import_saved_newmail(importer, newmail); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2439 return TRUE; |
14584 | 2440 } |
2441 /* fallback to saving from remote stream */ | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2442 if (!remote_mail) { |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2443 /* the mail isn't remote yet. we were just trying to copy a |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2444 local mail to avoid downloading the remote mail. */ |
19084 | 2445 mailbox_save_cancel(&save_ctx); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2446 return FALSE; |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2447 } |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2448 if (mail->minimal_fields) { |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2449 struct dsync_mail mail2; |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2450 const char *error_field; |
14584 | 2451 |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2452 i_assert(mail->input_mail != NULL); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2453 |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2454 if (dsync_mail_fill_nonminimal(mail->input_mail, &mail2, |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2455 &error_field) < 0) { |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2456 i_error("Mailbox %s: Failed to read mail %s uid=%u: %s", |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2457 mailbox_get_vname(importer->box), |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2458 error_field, mail->uid, |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2459 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2460 &importer->mail_error)); |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2461 importer->failed = TRUE; |
17982
d92c1c666bc3
dsync: Fixed assert-crash / memory leak on error handling path.
Timo Sirainen <tss@iki.fi>
parents:
17890
diff
changeset
|
2462 mailbox_save_cancel(&save_ctx); |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2463 return TRUE; |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2464 } |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2465 dsync_mailbox_save_set_nonminimal(save_ctx, &mail2); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2466 input = mail2.input; |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2467 } else { |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2468 input = mail->input; |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2469 } |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2470 |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2471 if (input == NULL) { |
14584 | 2472 /* it was just expunged in remote, skip it */ |
2473 mailbox_save_cancel(&save_ctx); | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2474 return TRUE; |
14584 | 2475 } |
2476 | |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2477 i_stream_seek(input, 0); |
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2478 if (mailbox_save_begin(&save_ctx, input) < 0) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2479 i_error("Mailbox %s: Saving failed: %s", |
14584 | 2480 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2481 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2482 &importer->mail_error)); |
14584 | 2483 importer->failed = TRUE; |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2484 return TRUE; |
14584 | 2485 } |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2486 while ((ret = i_stream_read(input)) > 0 || ret == -2) { |
14584 | 2487 if (mailbox_save_continue(save_ctx) < 0) { |
2488 save_failed = TRUE; | |
2489 ret = -1; | |
2490 break; | |
2491 } | |
2492 } | |
2493 i_assert(ret == -1); | |
2494 | |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2495 if (input->stream_errno != 0) { |
16940
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
2496 i_error("Mailbox %s: read(msg input) failed: %s", |
38f404297728
dsync: Use i_stream_get_error() instead of just errno in stream error messages.
Timo Sirainen <tss@iki.fi>
parents:
16832
diff
changeset
|
2497 mailbox_get_vname(importer->box), |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2498 i_stream_get_error(input)); |
14584 | 2499 mailbox_save_cancel(&save_ctx); |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2500 importer->mail_error = MAIL_ERROR_TEMP; |
14584 | 2501 importer->failed = TRUE; |
2502 } else if (save_failed) { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2503 i_error("Mailbox %s: Saving failed: %s", |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2504 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2505 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2506 &importer->mail_error)); |
14584 | 2507 mailbox_save_cancel(&save_ctx); |
2508 importer->failed = TRUE; | |
2509 } else { | |
17845
d2e1b3f6d13b
dsync: Added DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH to avoid opening mails unnecessarily.
Timo Sirainen <tss@iki.fi>
parents:
17518
diff
changeset
|
2510 i_assert(input->eof); |
14584 | 2511 if (mailbox_save_finish(&save_ctx) < 0) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2512 i_error("Mailbox %s: Saving failed: %s", |
14584 | 2513 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2514 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2515 &importer->mail_error)); |
14584 | 2516 importer->failed = TRUE; |
2517 } else { | |
22043
81e013b3207d
dsync: Try to commit transactions every dsync_commit_msgs_interval messages
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21814
diff
changeset
|
2518 dsync_mailbox_import_saved_newmail(importer, newmail); |
14584 | 2519 } |
2520 } | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2521 return TRUE; |
14584 | 2522 } |
2523 | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2524 static bool dsync_mailbox_save_newmails(struct dsync_mailbox_importer *importer, |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2525 const struct dsync_mail *mail, |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2526 struct importer_new_mail *all_newmails, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2527 bool remote_mail) |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2528 { |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2529 struct importer_new_mail *newmail, *all_newmails_forcopy; |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2530 bool ret = TRUE; |
17174
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2531 |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2532 /* if all_newmails list is large, avoid scanning through the |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2533 uninteresting ones for each newmail */ |
ea737947fac8
dsync: Optimization for a large number of mails with the same GUID.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
2534 all_newmails_forcopy = all_newmails; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2535 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2536 /* save all instances of the message */ |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2537 for (newmail = all_newmails; newmail != NULL && ret; newmail = newmail->next) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2538 if (!newmail->skip) T_BEGIN { |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2539 if (!dsync_mailbox_save_body(importer, mail, newmail, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2540 &all_newmails_forcopy, |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2541 remote_mail)) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2542 ret = FALSE; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2543 } T_END; |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2544 } |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2545 return ret; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2546 } |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2547 |
19696
3cc82c8c1b72
dsync: If mailbox importing fails, stop immediately without waiting for exporter to finish.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19670
diff
changeset
|
2548 int dsync_mailbox_import_mail(struct dsync_mailbox_importer *importer, |
3cc82c8c1b72
dsync: If mailbox importing fails, stop immediately without waiting for exporter to finish.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19670
diff
changeset
|
2549 const struct dsync_mail *mail) |
14584 | 2550 { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2551 struct importer_new_mail *all_newmails; |
14584 | 2552 |
15658
3a395a61f109
dsync: Fixed crashes when sending already expunged messages.
Timo Sirainen <tss@iki.fi>
parents:
15657
diff
changeset
|
2553 i_assert(mail->input == NULL || mail->input->seekable); |
14584 | 2554 i_assert(importer->new_uids_assigned); |
2555 | |
16254
e0acf38f6199
dsync: If saving mails fail, stop trying to save more of them and flooding logs.
Timo Sirainen <tss@iki.fi>
parents:
16206
diff
changeset
|
2556 if (importer->failed) |
19696
3cc82c8c1b72
dsync: If mailbox importing fails, stop immediately without waiting for exporter to finish.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19670
diff
changeset
|
2557 return -1; |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
2558 if (importer->require_full_resync) |
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
2559 return 0; |
16254
e0acf38f6199
dsync: If saving mails fail, stop trying to save more of them and flooding logs.
Timo Sirainen <tss@iki.fi>
parents:
16206
diff
changeset
|
2560 |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2561 imp_debug(importer, "Import mail body for GUID=%s UID=%u", |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2562 mail->guid, mail->uid); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2563 |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2564 all_newmails = *mail->guid != '\0' ? |
14584 | 2565 hash_table_lookup(importer->import_guids, mail->guid) : |
14923
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2566 hash_table_lookup(importer->import_uids, POINTER_CAST(mail->uid)); |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2567 if (all_newmails == NULL) { |
14584 | 2568 if (importer->want_mail_requests) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2569 i_error("Mailbox %s: Remote sent unwanted message body for " |
14584 | 2570 "GUID=%s UID=%u", |
2571 mailbox_get_vname(importer->box), | |
2572 mail->guid, mail->uid); | |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2573 } else { |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2574 imp_debug(importer, "Skip unwanted mail body for " |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2575 "GUID=%s UID=%u", mail->guid, mail->uid); |
14584 | 2576 } |
19696
3cc82c8c1b72
dsync: If mailbox importing fails, stop immediately without waiting for exporter to finish.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19670
diff
changeset
|
2577 return 0; |
14584 | 2578 } |
2579 if (*mail->guid != '\0') | |
2580 hash_table_remove(importer->import_guids, mail->guid); | |
14923
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2581 else { |
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2582 hash_table_remove(importer->import_uids, |
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2583 POINTER_CAST(mail->uid)); |
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2584 } |
16539
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2585 importer->import_pos++; |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2586 if (!dsync_mailbox_save_newmails(importer, mail, all_newmails, TRUE)) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2587 i_unreached(); |
19696
3cc82c8c1b72
dsync: If mailbox importing fails, stop immediately without waiting for exporter to finish.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19670
diff
changeset
|
2588 return importer->failed ? -1 : 0; |
14584 | 2589 } |
2590 | |
2591 static int | |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2592 reassign_uids_in_seq_range(struct dsync_mailbox_importer *importer, |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2593 const ARRAY_TYPE(seq_range) *unwanted_uids) |
14584 | 2594 { |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2595 struct mailbox *box = importer->box; |
14584 | 2596 const enum mailbox_transaction_flags trans_flags = |
2597 MAILBOX_TRANSACTION_FLAG_EXTERNAL | | |
2598 MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS; | |
2599 struct mailbox_transaction_context *trans; | |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2600 struct mail_search_args *search_args; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2601 struct mail_search_arg *arg; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2602 struct mail_search_context *search_ctx; |
14584 | 2603 struct mail_save_context *save_ctx; |
2604 struct mail *mail; | |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2605 unsigned int renumber_count = 0; |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2606 int ret = 1; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2607 |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2608 if (array_count(unwanted_uids) == 0) |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2609 return 1; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2610 |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2611 if (importer->debug) T_BEGIN { |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2612 string_t *str = t_str_new(256); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2613 imap_write_seq_range(str, unwanted_uids); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2614 imp_debug(importer, "Reassign UIDs: %s", str_c(str)); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2615 } T_END; |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2616 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2617 search_args = mail_search_build_init(); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2618 arg = mail_search_build_add(search_args, SEARCH_UIDSET); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2619 p_array_init(&arg->value.seqset, search_args->pool, |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2620 array_count(unwanted_uids)); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2621 array_append_array(&arg->value.seqset, unwanted_uids); |
14584 | 2622 |
2623 trans = mailbox_transaction_begin(box, trans_flags); | |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2624 search_ctx = mailbox_search_init(trans, search_args, NULL, 0, NULL); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2625 mail_search_args_unref(&search_args); |
14584 | 2626 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2627 while (mailbox_search_next(search_ctx, &mail)) { |
14584 | 2628 save_ctx = mailbox_save_alloc(trans); |
2629 mailbox_save_copy_flags(save_ctx, mail); | |
15233
f417cab3a21f
dsync: Use mailbox_move() to reassign UIDs instead of copy+expunge.
Timo Sirainen <tss@iki.fi>
parents:
15232
diff
changeset
|
2630 if (mailbox_move(&save_ctx, mail) < 0) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2631 i_error("Mailbox %s: Couldn't move mail within mailbox: %s", |
15233
f417cab3a21f
dsync: Use mailbox_move() to reassign UIDs instead of copy+expunge.
Timo Sirainen <tss@iki.fi>
parents:
15232
diff
changeset
|
2632 mailbox_get_vname(box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2633 mailbox_get_last_internal_error(box, &importer->mail_error)); |
14584 | 2634 ret = -1; |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2635 } else if (ret > 0) { |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2636 ret = 0; |
15233
f417cab3a21f
dsync: Use mailbox_move() to reassign UIDs instead of copy+expunge.
Timo Sirainen <tss@iki.fi>
parents:
15232
diff
changeset
|
2637 } |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2638 renumber_count++; |
14584 | 2639 } |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2640 if (mailbox_search_deinit(&search_ctx) < 0) { |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2641 i_error("Mailbox %s: mail search failed: %s", |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2642 mailbox_get_vname(box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2643 mailbox_get_last_internal_error(box, &importer->mail_error)); |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2644 ret = -1; |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2645 } |
14584 | 2646 |
2647 if (mailbox_transaction_commit(&trans) < 0) { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2648 i_error("Mailbox %s: UID reassign commit failed: %s", |
14584 | 2649 mailbox_get_vname(box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2650 mailbox_get_last_internal_error(box, &importer->mail_error)); |
14584 | 2651 ret = -1; |
2652 } | |
16793
2ce07adab319
dsync: Added more consistency when debug logging about changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16792
diff
changeset
|
2653 if (ret == 0) { |
2ce07adab319
dsync: Added more consistency when debug logging about changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16792
diff
changeset
|
2654 imp_debug(importer, "Mailbox %s: Change during sync: " |
2ce07adab319
dsync: Added more consistency when debug logging about changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16792
diff
changeset
|
2655 "Renumbered %u of %u unwanted UIDs", |
2ce07adab319
dsync: Added more consistency when debug logging about changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16792
diff
changeset
|
2656 mailbox_get_vname(box), |
2ce07adab319
dsync: Added more consistency when debug logging about changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16792
diff
changeset
|
2657 renumber_count, array_count(unwanted_uids)); |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2658 } |
14584 | 2659 return ret; |
2660 } | |
2661 | |
15617 | 2662 static int |
14584 | 2663 reassign_unwanted_uids(struct dsync_mailbox_importer *importer, |
21256
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2664 const char **changes_during_sync_r) |
14584 | 2665 { |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2666 ARRAY_TYPE(seq_range) unwanted_uids; |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2667 const uint32_t *wanted_uids, *saved_uids; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2668 uint32_t highest_seen_uid; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2669 unsigned int i, wanted_count, saved_count; |
14584 | 2670 int ret = 0; |
2671 | |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2672 wanted_uids = array_get(&importer->wanted_uids, &wanted_count); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2673 saved_uids = array_get(&importer->saved_uids, &saved_count); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2674 i_assert(wanted_count == saved_count); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2675 if (wanted_count == 0) |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2676 return 0; |
15612
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2677 /* wanted_uids contains the UIDs we tried to save mails with. |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2678 if nothing changed during dsync, we should have the expected UIDs |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2679 (saved_uids) and all is well. |
15612
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2680 |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2681 if any new messages got inserted during dsync, we'll need to fix up |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2682 the UIDs and let the next dsync fix up the other side. for example: |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2683 |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2684 remote uids = 5,7,9 = wanted_uids |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2685 remote uidnext = 12 |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2686 locally added new uid=5 -> |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2687 saved_uids = 10,7,9 |
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2688 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2689 we'll now need to reassign UIDs 5 and 10. to be fully future-proof |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2690 we'll reassign all UIDs between [original local uidnext .. highest |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2691 UID we think we know] that aren't in saved_uids. */ |
15612
a0493fa018fa
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15611
diff
changeset
|
2692 |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2693 /* create uidset for the list of UIDs we don't want to exist */ |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2694 t_array_init(&unwanted_uids, 8); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2695 highest_seen_uid = I_MAX(importer->remote_uid_next-1, |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2696 importer->highest_wanted_uid); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2697 i_assert(importer->local_uid_next <= highest_seen_uid); |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2698 seq_range_array_add_range(&unwanted_uids, |
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2699 importer->local_uid_next, highest_seen_uid); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2700 for (i = 0; i < wanted_count; i++) { |
14584 | 2701 i_assert(i < wanted_count); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2702 if (saved_uids[i] == wanted_uids[i]) |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2703 seq_range_array_remove(&unwanted_uids, saved_uids[i]); |
14584 | 2704 } |
2705 | |
16762
393c389b1540
dsync: Improved debug/error logging for changes during sync.
Timo Sirainen <tss@iki.fi>
parents:
16680
diff
changeset
|
2706 ret = reassign_uids_in_seq_range(importer, &unwanted_uids); |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2707 if (ret == 0) { |
21256
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2708 *changes_during_sync_r = t_strdup_printf( |
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2709 "%u UIDs changed due to UID conflicts", |
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2710 seq_range_count(&unwanted_uids)); |
15781
5a3586ffc644
dsync: If unexpected changes happen during sync, return a safe last-common-uid for state.
Timo Sirainen <tss@iki.fi>
parents:
15779
diff
changeset
|
2711 /* conflicting changes during sync, revert our last-common-uid |
5a3586ffc644
dsync: If unexpected changes happen during sync, return a safe last-common-uid for state.
Timo Sirainen <tss@iki.fi>
parents:
15779
diff
changeset
|
2712 back to a safe value. */ |
5a3586ffc644
dsync: If unexpected changes happen during sync, return a safe last-common-uid for state.
Timo Sirainen <tss@iki.fi>
parents:
15779
diff
changeset
|
2713 importer->last_common_uid = importer->local_uid_next - 1; |
5a3586ffc644
dsync: If unexpected changes happen during sync, return a safe last-common-uid for state.
Timo Sirainen <tss@iki.fi>
parents:
15779
diff
changeset
|
2714 } |
15824
953594b35bb3
dsync: Fixes to handling local changes during dsync.
Timo Sirainen <tss@iki.fi>
parents:
15820
diff
changeset
|
2715 return ret < 0 ? -1 : 0; |
14584 | 2716 } |
2717 | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2718 static int |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2719 dsync_mailbox_import_commit(struct dsync_mailbox_importer *importer, bool final) |
14584 | 2720 { |
2721 struct mail_transaction_commit_changes changes; | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2722 struct seq_range_iter iter; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2723 uint32_t uid; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2724 unsigned int n; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2725 int ret = importer->failed ? -1 : 0; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2726 |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2727 mail_free(&importer->mail); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2728 mail_free(&importer->ext_mail); |
14584 | 2729 |
2730 /* commit saves */ | |
2731 if (mailbox_transaction_commit_get_changes(&importer->ext_trans, | |
2732 &changes) < 0) { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2733 i_error("Mailbox %s: Save commit failed: %s", |
14584 | 2734 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2735 mailbox_get_last_internal_error(importer->box, &importer->mail_error)); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2736 /* removed wanted_uids that weren't actually saved */ |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2737 array_delete(&importer->wanted_uids, |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2738 array_count(&importer->saved_uids), |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2739 array_count(&importer->wanted_uids) - |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2740 array_count(&importer->saved_uids)); |
14584 | 2741 mailbox_transaction_rollback(&importer->trans); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2742 ret = -1; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2743 } else { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2744 /* remember the UIDs that were successfully saved */ |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2745 if (importer->debug) T_BEGIN { |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2746 string_t *str = t_str_new(256); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2747 imap_write_seq_range(str, &changes.saved_uids); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2748 imp_debug(importer, "Saved UIDs: %s", str_c(str)); |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2749 } T_END; |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2750 seq_range_array_iter_init(&iter, &changes.saved_uids); n = 0; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2751 while (seq_range_array_iter_nth(&iter, n++, &uid)) |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2752 array_append(&importer->saved_uids, &uid, 1); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2753 pool_unref(&changes.pool); |
14584 | 2754 |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2755 /* commit flag changes and expunges */ |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2756 if (mailbox_transaction_commit(&importer->trans) < 0) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2757 i_error("Mailbox %s: Commit failed: %s", |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2758 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2759 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2760 &importer->mail_error)); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2761 ret = -1; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2762 } |
14584 | 2763 } |
2764 | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2765 if (!final) |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2766 dsync_mailbox_import_transaction_begin(importer); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2767 return ret; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2768 } |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2769 |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2770 static int dsync_mailbox_import_finish(struct dsync_mailbox_importer *importer, |
21256
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2771 const char **changes_during_sync_r) |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2772 { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2773 struct mailbox_update update; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2774 int ret; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2775 |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2776 ret = dsync_mailbox_import_commit(importer, TRUE); |
14584 | 2777 |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2778 if (ret == 0) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2779 /* update mailbox metadata if we successfully saved |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2780 everything. */ |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21267
diff
changeset
|
2781 i_zero(&update); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2782 update.min_next_uid = importer->remote_uid_next; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2783 update.min_first_recent_uid = |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2784 I_MIN(importer->last_common_uid+1, |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2785 importer->remote_first_recent_uid); |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2786 update.min_highest_modseq = importer->remote_highest_modseq; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2787 update.min_highest_pvt_modseq = importer->remote_highest_pvt_modseq; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2788 |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2789 imp_debug(importer, "Finish update: min_next_uid=%u " |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2790 "min_first_recent_uid=%u min_highest_modseq=%llu " |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2791 "min_highest_pvt_modseq=%llu", |
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2792 update.min_next_uid, update.min_first_recent_uid, |
17272 | 2793 (unsigned long long)update.min_highest_modseq, |
2794 (unsigned long long)update.min_highest_pvt_modseq); | |
16792
4a969a2e9399
dsync: Added some more debug logging.
Timo Sirainen <tss@iki.fi>
parents:
16762
diff
changeset
|
2795 |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2796 if (mailbox_update(importer->box, &update) < 0) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2797 i_error("Mailbox %s: Update failed: %s", |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2798 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2799 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2800 &importer->mail_error)); |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2801 ret = -1; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2802 } |
14584 | 2803 } |
2804 | |
2805 /* sync mailbox to finish flag changes and expunges. */ | |
2806 if (mailbox_sync(importer->box, 0) < 0) { | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2807 i_error("Mailbox %s: Sync failed: %s", |
14584 | 2808 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2809 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2810 &importer->mail_error)); |
14584 | 2811 ret = -1; |
2812 } | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2813 if (ret == 0) { |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2814 /* give new UIDs to messages that got saved with unwanted UIDs. |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2815 do it only if the whole transaction succeeded. */ |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2816 if (reassign_unwanted_uids(importer, changes_during_sync_r) < 0) |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2817 ret = -1; |
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2818 } |
14584 | 2819 return ret; |
2820 } | |
2821 | |
15662
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2822 static void |
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2823 dsync_mailbox_import_check_missing_guid_imports(struct dsync_mailbox_importer *importer) |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2824 { |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2825 struct hash_iterate_context *iter; |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2826 const char *key; |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2827 struct importer_new_mail *mail; |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2828 |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2829 iter = hash_table_iterate_init(importer->import_guids); |
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2830 while (hash_table_iterate(iter, importer->import_guids, &key, &mail)) { |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2831 for (; mail != NULL; mail = mail->next) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2832 if (mail->skip) |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2833 continue; |
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2834 |
15662
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2835 i_error("Mailbox %s: Remote didn't send mail GUID=%s (UID=%u)", |
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2836 mailbox_get_vname(importer->box), |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2837 mail->guid, mail->remote_uid); |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2838 importer->mail_error = MAIL_ERROR_TEMP; |
16132
0eef38d78069
dsync: If remote doesn't send some mails, don't exit with code 0.
Timo Sirainen <tss@iki.fi>
parents:
16117
diff
changeset
|
2839 importer->failed = TRUE; |
14918
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2840 } |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2841 } |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2842 hash_table_iterate_deinit(&iter); |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2843 } |
8eae4e205c82
Hash table API is now (mostly) type safe.
Timo Sirainen <tss@iki.fi>
parents:
14917
diff
changeset
|
2844 |
15662
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2845 static void |
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2846 dsync_mailbox_import_check_missing_uid_imports(struct dsync_mailbox_importer *importer) |
14584 | 2847 { |
2848 struct hash_iterate_context *iter; | |
14923
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2849 void *key; |
96fd2c3bf932
Reverted "support for non-pointers" part of the hash table API changes.
Timo Sirainen <tss@iki.fi>
parents:
14922
diff
changeset
|
2850 struct importer_new_mail *mail; |
14584 | 2851 |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2852 iter = hash_table_iterate_init(importer->import_uids); |
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2853 while (hash_table_iterate(iter, importer->import_uids, &key, &mail)) { |
14584 | 2854 for (; mail != NULL; mail = mail->next) { |
15772
360661d99c42
dsync: Various importer fixes.
Timo Sirainen <tss@iki.fi>
parents:
15770
diff
changeset
|
2855 if (mail->skip) |
15611
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2856 continue; |
cc77431b09b4
dsync: Don't wrongly log errors about missing message bodies.
Timo Sirainen <tss@iki.fi>
parents:
15591
diff
changeset
|
2857 |
15662
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2858 i_error("Mailbox %s: Remote didn't send mail UID=%u", |
fc5c3281d6d3
dsync: If remote doesn't send some message bodies, log an error about each one separately.
Timo Sirainen <tss@iki.fi>
parents:
15661
diff
changeset
|
2859 mailbox_get_vname(importer->box), |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2860 mail->remote_uid); |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2861 importer->mail_error = MAIL_ERROR_TEMP; |
16132
0eef38d78069
dsync: If remote doesn't send some mails, don't exit with code 0.
Timo Sirainen <tss@iki.fi>
parents:
16117
diff
changeset
|
2862 importer->failed = TRUE; |
14584 | 2863 } |
2864 } | |
2865 hash_table_iterate_deinit(&iter); | |
2866 } | |
2867 | |
2868 int dsync_mailbox_import_deinit(struct dsync_mailbox_importer **_importer, | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2869 bool success, |
14584 | 2870 uint32_t *last_common_uid_r, |
2871 uint64_t *last_common_modseq_r, | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2872 uint64_t *last_common_pvt_modseq_r, |
17282
9669c9a8984f
dsync: Include messages_count in the mailbox states.
Timo Sirainen <tss@iki.fi>
parents:
17272
diff
changeset
|
2873 uint32_t *last_messages_count_r, |
21256
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2874 const char **changes_during_sync_r, |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
2875 bool *require_full_resync_r, |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2876 enum mail_error *error_r) |
14584 | 2877 { |
2878 struct dsync_mailbox_importer *importer = *_importer; | |
17282
9669c9a8984f
dsync: Include messages_count in the mailbox states.
Timo Sirainen <tss@iki.fi>
parents:
17272
diff
changeset
|
2879 struct mailbox_status status; |
14584 | 2880 int ret; |
2881 | |
2882 *_importer = NULL; | |
21256
4ac3461df334
dsync: When logging "Mailbox changed caused a desync", log also the reason.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20831
diff
changeset
|
2883 *changes_during_sync_r = NULL; |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
2884 *require_full_resync_r = importer->require_full_resync; |
14584 | 2885 |
20074
7a29a0930b63
dsync: If state is invalid, exit with code 2 instead of tempfail.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20072
diff
changeset
|
2886 if ((!success || importer->require_full_resync) && !importer->failed) { |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2887 importer->mail_error = MAIL_ERROR_TEMP; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2888 importer->failed = TRUE; |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2889 } |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2890 |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2891 if (!importer->new_uids_assigned && !importer->failed) |
14584 | 2892 dsync_mailbox_import_assign_new_uids(importer); |
2893 | |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2894 if (!importer->failed) { |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2895 dsync_mailbox_import_check_missing_guid_imports(importer); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2896 dsync_mailbox_import_check_missing_uid_imports(importer); |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2897 } |
14584 | 2898 |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
2899 if (importer->search_ctx != NULL) { |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2900 if (mailbox_search_deinit(&importer->search_ctx) < 0) { |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2901 i_error("Mailbox %s: Search failed: %s", |
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2902 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2903 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2904 &importer->mail_error)); |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
2905 importer->failed = TRUE; |
15766
4260244e57e2
dsync: Various importer fixes. Handle unexpectedly wrong mailbox state better.
Timo Sirainen <tss@iki.fi>
parents:
15754
diff
changeset
|
2906 } |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14676
diff
changeset
|
2907 } |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2908 if (dsync_mailbox_import_finish(importer, changes_during_sync_r) < 0) |
14584 | 2909 importer->failed = TRUE; |
2910 | |
18180
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2911 if (importer->virtual_mail != NULL) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2912 mail_free(&importer->virtual_mail); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2913 if (importer->virtual_trans != NULL) |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2914 (void)mailbox_transaction_commit(&importer->virtual_trans); |
39d00448490f
dsync: If same GUID already exists in storage, try to copy it instead of recreating the mail.
Timo Sirainen <tss@iki.fi>
parents:
18178
diff
changeset
|
2915 |
14584 | 2916 hash_table_destroy(&importer->import_guids); |
2917 hash_table_destroy(&importer->import_uids); | |
2918 array_free(&importer->maybe_expunge_uids); | |
2919 array_free(&importer->maybe_saves); | |
2920 array_free(&importer->wanted_uids); | |
16255
548e59794f2e
dsync: Commit large transactions every 100 new messages.
Timo Sirainen <tss@iki.fi>
parents:
16254
diff
changeset
|
2921 array_free(&importer->saved_uids); |
14584 | 2922 array_free(&importer->newmails); |
2923 if (array_is_created(&importer->mail_requests)) | |
2924 array_free(&importer->mail_requests); | |
2925 | |
2926 *last_common_uid_r = importer->last_common_uid; | |
21267
b60c7b697838
dsync: Fixed boolean expression in dsync_mailbox_import_deinit().
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21256
diff
changeset
|
2927 if (*changes_during_sync_r == NULL) { |
15232
6c850258002f
doveadm sync/backup: Added -s <state> parameter to do a fast stateful sync.
Timo Sirainen <tss@iki.fi>
parents:
14926
diff
changeset
|
2928 *last_common_modseq_r = importer->remote_highest_modseq; |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2929 *last_common_pvt_modseq_r = importer->remote_highest_pvt_modseq; |
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2930 } else { |
14584 | 2931 /* local changes occurred during dsync. we exported changes up |
2932 to local_initial_highestmodseq, so all of the changes have | |
2933 happened after it. we want the next run to see those changes, | |
2934 so return it as the last common modseq */ | |
2935 *last_common_modseq_r = importer->local_initial_highestmodseq; | |
15496
5d90e2aa1ba8
dsync: Use private modseqs to support syncing private flags in shared mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
15257
diff
changeset
|
2936 *last_common_pvt_modseq_r = importer->local_initial_highestpvtmodseq; |
14584 | 2937 } |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2938 if (importer->delete_mailbox) { |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2939 if (mailbox_delete(importer->box) < 0) { |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2940 i_error("Couldn't delete mailbox %s: %s", |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2941 mailbox_get_vname(importer->box), |
21814
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2942 mailbox_get_last_internal_error(importer->box, |
759962e70148
global: Log internal storage error on failure
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents:
21390
diff
changeset
|
2943 &importer->mail_error)); |
17859
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2944 importer->failed = TRUE; |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2945 } |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2946 *last_messages_count_r = 0; |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2947 } else { |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2948 mailbox_get_open_status(importer->box, STATUS_MESSAGES, &status); |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2949 *last_messages_count_r = status.messages; |
c02918434721
doveadm backup: Locally expunged mails weren't always added back.
Timo Sirainen <tss@iki.fi>
parents:
17845
diff
changeset
|
2950 } |
14584 | 2951 |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2952 i_assert(importer->failed == (importer->mail_error != 0)); |
14584 | 2953 ret = importer->failed ? -1 : 0; |
18371
b900b50085fc
dsync: Use storage's mail_error to choose the doveadm exit code.
Timo Sirainen <tss@iki.fi>
parents:
18183
diff
changeset
|
2954 *error_r = importer->mail_error; |
14584 | 2955 pool_unref(&importer->pool); |
2956 return ret; | |
2957 } | |
16539
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2958 |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2959 const char *dsync_mailbox_import_get_proctitle(struct dsync_mailbox_importer *importer) |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2960 { |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2961 if (importer->search_ctx != NULL) |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2962 return ""; |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2963 return t_strdup_printf("%u/%u", importer->import_pos, |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2964 importer->import_count); |
b5876fa03b0e
dsync: If verbose_proctitle=yes, show the current state in it.
Timo Sirainen <tss@iki.fi>
parents:
16259
diff
changeset
|
2965 } |