1 #ifndef DSYNC_BRAIN_PRIVATE_H
2 #define DSYNC_BRAIN_PRIVATE_H
3 
4 #include "hash.h"
5 #include "dsync-brain.h"
6 #include "dsync-mailbox.h"
7 #include "dsync-mailbox-state.h"
8 
9 #define DSYNC_LOCK_FILENAME ".dovecot-sync.lock"
10 #define DSYNC_MAILBOX_LOCK_FILENAME ".dovecot-box-sync.lock"
11 #define DSYNC_MAILBOX_DEFAULT_LOCK_TIMEOUT_SECS 30
12 
13 struct dsync_mailbox_tree_sync_change;
14 
15 enum dsync_state {
16 	DSYNC_STATE_MASTER_RECV_HANDSHAKE,
17 	DSYNC_STATE_SLAVE_RECV_HANDSHAKE,
18 	/* if sync_type=STATE, the master brain knows the saved "last common
19 	   mailbox state". this state is sent to the slave. */
20 	DSYNC_STATE_MASTER_SEND_LAST_COMMON,
21 	DSYNC_STATE_SLAVE_RECV_LAST_COMMON,
22 
23 	/* both sides send their mailbox trees */
24 	DSYNC_STATE_SEND_MAILBOX_TREE,
25 	DSYNC_STATE_SEND_MAILBOX_TREE_DELETES,
26 	DSYNC_STATE_RECV_MAILBOX_TREE,
27 	DSYNC_STATE_RECV_MAILBOX_TREE_DELETES,
28 
29 	/* master decides in which order mailboxes are synced (it knows the
30 	   slave's mailboxes by looking at the received mailbox tree) */
31 	DSYNC_STATE_MASTER_SEND_MAILBOX,
32 	DSYNC_STATE_SLAVE_RECV_MAILBOX,
33 	/* once mailbox is selected, the mails inside it are synced.
34 	   after the mails are synced, another mailbox is synced. */
35 	DSYNC_STATE_SYNC_MAILS,
36 
37 	DSYNC_STATE_FINISH,
38 	DSYNC_STATE_DONE
39 };
40 
41 enum dsync_box_state {
42 	DSYNC_BOX_STATE_MAILBOX,
43 	DSYNC_BOX_STATE_CHANGES,
44 	DSYNC_BOX_STATE_ATTRIBUTES,
45 	DSYNC_BOX_STATE_MAIL_REQUESTS,
46 	DSYNC_BOX_STATE_MAILS,
47 	DSYNC_BOX_STATE_RECV_LAST_COMMON,
48 	DSYNC_BOX_STATE_DONE
49 };
50 
51 struct dsync_brain {
52 	pool_t pool;
53 	struct mail_user *user;
54 	struct dsync_ibc *ibc;
55 	const char *process_title_prefix;
56 	ARRAY(struct mail_namespace *) sync_namespaces;
57 	const char *sync_box;
58 	struct mailbox *virtual_all_box;
59 	guid_128_t sync_box_guid;
60 	const char *const *exclude_mailboxes;
61 	enum dsync_brain_sync_type sync_type;
62 	time_t sync_since_timestamp;
63 	time_t sync_until_timestamp;
64 	uoff_t sync_max_size;
65 	const char *sync_flag;
66 	char alt_char;
67 	unsigned int import_commit_msgs_interval;
68 	unsigned int hdr_hash_version;
69 
70 	unsigned int lock_timeout;
71 	int lock_fd;
72 	const char *lock_path;
73 	struct file_lock *lock;
74 
75 	char hierarchy_sep;
76 	struct dsync_mailbox_tree *local_mailbox_tree;
77 	struct dsync_mailbox_tree *remote_mailbox_tree;
78 	struct dsync_mailbox_tree_iter *local_tree_iter;
79 
80 	enum dsync_state state, pre_box_state;
81 	enum dsync_box_state box_recv_state;
82 	enum dsync_box_state box_send_state;
83 	unsigned int proctitle_update_counter;
84 
85 	struct dsync_transaction_log_scan *log_scan;
86 	struct dsync_mailbox_importer *box_importer;
87 	struct dsync_mailbox_exporter *box_exporter;
88 
89 	struct mailbox *box;
90 	struct file_lock *box_lock;
91 	unsigned int mailbox_lock_timeout_secs;
92 	struct dsync_mailbox local_dsync_box, remote_dsync_box;
93 	pool_t dsync_box_pool;
94 	/* list of mailbox states
95 	   for master brain: given to brain at init and
96 	   for slave brain: received from DSYNC_STATE_SLAVE_RECV_LAST_COMMON */
97 	HASH_TABLE_TYPE(dsync_mailbox_state) mailbox_states;
98 	/* DSYNC_STATE_MASTER_SEND_LAST_COMMON: current send position */
99 	struct hash_iterate_context *mailbox_states_iter;
100 	/* state of the mailbox we're currently syncing, changed at
101 	   init and deinit */
102 	struct dsync_mailbox_state mailbox_state;
103 	/* new states for synced mailboxes */
104 	ARRAY_TYPE(dsync_mailbox_state) remote_mailbox_states;
105 
106 	const char *changes_during_sync;
107 	enum mail_error mail_error;
108 
109 	const char *const *hashed_headers;
110 
111 	bool master_brain:1;
112 	bool mail_requests:1;
113 	bool backup_send:1;
114 	bool backup_recv:1;
115 	bool purge:1;
116 	bool debug:1;
117 	bool sync_visible_namespaces:1;
118 	bool no_mail_sync:1;
119 	bool no_backup_overwrite:1;
120 	bool no_mail_prefetch:1;
121 	bool no_mailbox_renames:1;
122 	bool changes_during_remote_sync:1;
123 	bool require_full_resync:1;
124 	bool verbose_proctitle:1;
125 	bool no_notify:1;
126 	bool failed:1;
127 	bool empty_hdr_workaround:1;
128 };
129 
130 extern const char *dsync_box_state_names[DSYNC_BOX_STATE_DONE+1];
131 
132 void dsync_brain_mailbox_trees_init(struct dsync_brain *brain);
133 void dsync_brain_send_mailbox_tree(struct dsync_brain *brain);
134 void dsync_brain_send_mailbox_tree_deletes(struct dsync_brain *brain);
135 bool dsync_brain_recv_mailbox_tree(struct dsync_brain *brain);
136 bool dsync_brain_recv_mailbox_tree_deletes(struct dsync_brain *brain);
137 int dsync_brain_mailbox_tree_sync_change(struct dsync_brain *brain,
138 			const struct dsync_mailbox_tree_sync_change *change,
139 			enum mail_error *error_r);
140 
141 void dsync_brain_sync_mailbox_deinit(struct dsync_brain *brain);
142 int dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid,
143 			      struct mailbox **box_r, const char **errstr_r,
144 			      enum mail_error *error_r);
145 bool dsync_brain_mailbox_update_pre(struct dsync_brain *brain,
146 				    struct mailbox *box,
147 				    const struct dsync_mailbox *local_box,
148 				    const struct dsync_mailbox *remote_box,
149 				    const char **reason_r);
150 bool dsync_boxes_need_sync(struct dsync_brain *brain,
151 			   const struct dsync_mailbox *box1,
152 			   const struct dsync_mailbox *box2);
153 void dsync_brain_sync_init_box_states(struct dsync_brain *brain);
154 void dsync_brain_set_changes_during_sync(struct dsync_brain *brain,
155 					 const char *reason);
156 
157 void dsync_brain_master_send_mailbox(struct dsync_brain *brain);
158 bool dsync_brain_slave_recv_mailbox(struct dsync_brain *brain);
159 int dsync_brain_sync_mailbox_open(struct dsync_brain *brain,
160 				  const struct dsync_mailbox *remote_dsync_box);
161 bool dsync_brain_sync_mails(struct dsync_brain *brain);
162 
163 #endif
164