dsync-worker.h revision cd611ca82b8b8a61736d21a8a0de58cfd53bc9b6
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen#ifndef DSYNC_WORKER_H
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen#define DSYNC_WORKER_H
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen#include "ioloop.h"
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen#include "dsync-data.h"
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainenenum dsync_msg_get_result {
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen DSYNC_MSG_GET_RESULT_SUCCESS,
88ade75211d86266619d50aab44ccbdb7a151cbeTimo Sirainen DSYNC_MSG_GET_RESULT_EXPUNGED,
82d99ea82e0f87cd47ea196c2245f4c604fcc7a8Timo Sirainen DSYNC_MSG_GET_RESULT_FAILED
88ade75211d86266619d50aab44ccbdb7a151cbeTimo Sirainen};
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainenstruct dsync_worker_subscription {
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen const char *vname, *storage_name, *ns_prefix;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen time_t last_change;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen};
17e367eb70fbd5d200a4deaee062a044e1db3805Timo Sirainenstruct dsync_worker_unsubscription {
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen /* SHA1 sum of the mailbox's storage name, i.e. without namespace
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainen prefix */
82d99ea82e0f87cd47ea196c2245f4c604fcc7a8Timo Sirainen mailbox_guid_t name_sha1;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen const char *ns_prefix;
82d99ea82e0f87cd47ea196c2245f4c604fcc7a8Timo Sirainen time_t last_change;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen};
88ade75211d86266619d50aab44ccbdb7a151cbeTimo Sirainen
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainentypedef void dsync_worker_copy_callback_t(bool success, void *context);
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainentypedef void dsync_worker_save_callback_t(void *context);
e554622c1927eb3332500c962f46cba77e8c94a5Timo Sirainentypedef void dsync_worker_msg_callback_t(enum dsync_msg_get_result result,
const struct dsync_msg_static_data *data,
void *context);
typedef void dsync_worker_finish_callback_t(bool success, void *context);
struct dsync_worker *
dsync_worker_init_local(struct mail_user *user, const char *namespace_prefix,
char alt_char);
struct dsync_worker *dsync_worker_init_proxy_client(int fd_in, int fd_out);
void dsync_worker_deinit(struct dsync_worker **worker);
/* Set this worker as read-only. All attempted changes are ignored. */
void dsync_worker_set_readonly(struct dsync_worker *worker);
/* Log verbosely */
void dsync_worker_set_verbose(struct dsync_worker *worker);
/* If any function returns with "waiting for more data", the given callback
gets called when more data is available. */
void dsync_worker_set_input_callback(struct dsync_worker *worker,
io_callback_t *callback, void *context);
/* Returns TRUE if command queue is full and caller should stop sending
more commands. */
bool dsync_worker_is_output_full(struct dsync_worker *worker);
/* The given callback gets called when more commands can be queued. */
void dsync_worker_set_output_callback(struct dsync_worker *worker,
io_callback_t *callback, void *context);
/* Try to flush command queue. Returns 1 if all flushed, 0 if something is
still in queue, -1 if failed. */
int dsync_worker_output_flush(struct dsync_worker *worker);
/* Iterate though all mailboxes */
struct dsync_worker_mailbox_iter *
dsync_worker_mailbox_iter_init(struct dsync_worker *worker);
/* Get the next available mailbox. Returns 1 if ok, 0 if waiting for more data,
-1 if there are no more mailboxes. */
int dsync_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *iter,
struct dsync_mailbox *dsync_box_r);
/* Finish mailbox iteration. Returns 0 if ok, -1 if iteration failed. */
int dsync_worker_mailbox_iter_deinit(struct dsync_worker_mailbox_iter **iter);
/* Iterate though all subscriptions */
struct dsync_worker_subs_iter *
dsync_worker_subs_iter_init(struct dsync_worker *worker);
/* Get the next subscription. Returns 1 if ok, 0 if waiting for more data,
-1 if there are no more subscriptions. */
int dsync_worker_subs_iter_next(struct dsync_worker_subs_iter *iter,
struct dsync_worker_subscription *rec_r);
/* Like _iter_next(), but list known recent unsubscriptions. */
int dsync_worker_subs_iter_next_un(struct dsync_worker_subs_iter *iter,
struct dsync_worker_unsubscription *rec_r);
/* Finish subscription iteration. Returns 0 if ok, -1 if iteration failed. */
int dsync_worker_subs_iter_deinit(struct dsync_worker_subs_iter **iter);
/* Subscribe/unsubscribe mailbox */
void dsync_worker_set_subscribed(struct dsync_worker *worker,
const char *name, time_t last_change,
bool set);
/* Iterate through all messages in given mailboxes. The mailboxes are iterated
in the given order. */
struct dsync_worker_msg_iter *
dsync_worker_msg_iter_init(struct dsync_worker *worker,
const mailbox_guid_t mailboxes[],
unsigned int mailbox_count);
/* Get the next available message. Also returns all expunged messages from
the end of mailbox (if next_uid-1 message exists, nothing is returned).
mailbox_idx_r contains the mailbox's index in mailboxes[] array given
to _iter_init(). Returns 1 if ok, 0 if waiting for more data, -1 if there
are no more messages. */
int dsync_worker_msg_iter_next(struct dsync_worker_msg_iter *iter,
unsigned int *mailbox_idx_r,
struct dsync_message *msg_r);
/* Finish message iteration. Returns 0 if ok, -1 if iteration failed. */
int dsync_worker_msg_iter_deinit(struct dsync_worker_msg_iter **iter);
/* Create mailbox with given name, GUID and UIDVALIDITY. */
void dsync_worker_create_mailbox(struct dsync_worker *worker,
const struct dsync_mailbox *dsync_box);
/* Delete mailbox/dir with given GUID. */
void dsync_worker_delete_mailbox(struct dsync_worker *worker,
const struct dsync_mailbox *dsync_box);
/* Delete mailbox's directory. Fail if it would also delete mailbox. */
void dsync_worker_delete_dir(struct dsync_worker *worker,
const struct dsync_mailbox *dsync_box);
/* Change a mailbox and its childrens' name. The name is taken from the given
dsync_box (applying name_sep if necessary). */
void dsync_worker_rename_mailbox(struct dsync_worker *worker,
const mailbox_guid_t *mailbox,
const struct dsync_mailbox *dsync_box);
/* Find mailbox with given GUID and make sure its uid_next and
highest_modseq are up to date (but don't shrink them). */
void dsync_worker_update_mailbox(struct dsync_worker *worker,
const struct dsync_mailbox *dsync_box);
/* The following message syncing functions access the this selected mailbox. */
void dsync_worker_select_mailbox(struct dsync_worker *worker,
const struct dsync_mailbox *box);
/* Update message's metadata (flags, keywords, modseq). */
void dsync_worker_msg_update_metadata(struct dsync_worker *worker,
const struct dsync_message *msg);
/* Change message's UID. */
void dsync_worker_msg_update_uid(struct dsync_worker *worker,
uint32_t old_uid, uint32_t new_uid);
/* Expunge given message. */
void dsync_worker_msg_expunge(struct dsync_worker *worker, uint32_t uid);
/* Copy given message. */
void dsync_worker_msg_copy(struct dsync_worker *worker,
const mailbox_guid_t *src_mailbox, uint32_t src_uid,
const struct dsync_message *dest_msg,
dsync_worker_copy_callback_t *callback,
void *context);
/* Save given message from the given input stream. Once saving is finished,
the given callback is called and the stream is destroyed. */
void dsync_worker_msg_save(struct dsync_worker *worker,
const struct dsync_message *msg,
const struct dsync_msg_static_data *data,
dsync_worker_save_callback_t *callback,
void *context);
/* Cancel any pending saves */
void dsync_worker_msg_save_cancel(struct dsync_worker *worker);
/* Get message data for saving. The callback is called once when the static
data has been received. The whole message may not have been downloaded yet,
so the caller must read the input stream until it returns EOF and then
unreference it. */
void dsync_worker_msg_get(struct dsync_worker *worker,
const mailbox_guid_t *mailbox, uint32_t uid,
dsync_worker_msg_callback_t *callback, void *context);
/* Call the callback once all the pending commands are finished. */
void dsync_worker_finish(struct dsync_worker *worker,
dsync_worker_finish_callback_t *callback,
void *context);
/* Returns TRUE if some commands have failed. */
bool dsync_worker_has_failed(struct dsync_worker *worker);
/* Returns TRUE if some UID or modseq changes didn't get assigned as
requested. */
bool dsync_worker_has_unexpected_changes(struct dsync_worker *worker);
#endif