dsync-worker-local.c revision d3280fe317a4598c0868cc440e7a1191c06d0db3
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_list_iterate_context *list_iter;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct hash_iterate_context *deleted_dir_iter;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_list_iterate_context *list_iter;
e8762c2b4914db7997fa9eb644a91586952d1876Timo Sirainen /* mailbox_guid_t -> struct local_dsync_mailbox* */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* mailbox_guid_t -> struct local_dsync_mailbox_change* */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* <-> struct local_dsync_dir_change */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ARRAY_DEFINE(subs_namespaces, struct mail_namespace *);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ARRAY_DEFINE(msg_get_queue, struct local_dsync_worker_msg_get);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dsync_worker_finish_callback_t *finish_callback;
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenextern struct dsync_worker_vfuncs local_dsync_worker;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void local_worker_mailbox_close(struct local_dsync_worker *worker);
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainenstatic void local_worker_msg_box_close(struct local_dsync_worker *worker);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenlocal_worker_msg_get_next(struct local_dsync_worker *worker,
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen const struct local_dsync_worker_msg_get *get);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int mailbox_guid_cmp(const void *p1, const void *p2)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return memcmp(g1->guid, g2->guid, sizeof(g1->guid));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic unsigned int mailbox_guid_hash(const void *p)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, g, h = 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen h = (h << 4) + s[i];
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((g = h & 0xf0000000UL)) {
b8d314c6355009ad0b9e332b6acecdfac5cc8891Timo Sirainen h = h ^ (g >> 24);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* compare settings pointers so that it'll work
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for shared namespaces */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void dsync_drop_extra_namespaces(struct local_dsync_worker *worker)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace_settings *const *ns_unset, *const *ns_set;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!array_is_created(&user->unexpanded_set->namespaces))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* drop all namespaces that have a location defined internally */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns_unset = array_get(&user->unexpanded_set->namespaces, &count);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns_set = array_get(&user->set->namespaces, &count2);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < count; i++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* remember the subscriptions=no namespaces so we can
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen handle their subscriptions in parent namespaces
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_append(&worker->subs_namespaces, &ns, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("All your namespaces have a location setting. "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "It should be empty (default mail_location) in the "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "namespace to be converted.");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendsync_worker_init_local(struct mail_user *user, char alt_char)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("local dsync worker", 10240);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen worker = p_new(pool, struct local_dsync_worker, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen p_array_init(&worker->subs_namespaces, pool, 8);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void local_worker_deinit(struct dsync_worker *_worker)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_foreach_modifiable(&worker->subs_namespaces, nsp)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_destroy(&worker->mailbox_changes_hash);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_destroy(&worker->dir_changes_hash);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic bool local_worker_is_output_full(struct dsync_worker *worker ATTR_UNUSED)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int local_worker_output_flush(struct dsync_worker *worker ATTR_UNUSED)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendsync_worker_save_mailbox_change(struct local_dsync_worker *worker,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen change = hash_table_lookup(worker->mailbox_changes_hash,
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen change = i_new(struct local_dsync_mailbox_change, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_insert(worker->mailbox_changes_hash,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen stamp = mailbox_log_record_get_timestamp(rec);
d22301419109ed4a38351715e6760011421dadecTimo Sirainendsync_worker_save_dir_change(struct local_dsync_worker *worker,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct local_dsync_dir_change *change, new_change;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(new_change.name_sha1.guid, rec->mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen stamp = mailbox_log_record_get_timestamp(rec);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen change = hash_table_lookup(worker->dir_changes_hash, &new_change);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen change = i_new(struct local_dsync_dir_change, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_insert(worker->dir_changes_hash, change, change);
i_unreached();
static unsigned int mailbox_log_record_hash(const void *p)
static unsigned int dir_change_hash(const void *p)
int ret = 0;
return ret;
static struct dsync_worker_mailbox_iter *
const char *storage_name,
const char *storage_name;
const char *const *fields;
unsigned int i, field_count;
for (i = 0; i < field_count; i++) {
return ret;
static struct dsync_worker_subs_iter *
static struct mail_namespace *
return *nsp;
return NULL;
const char *storage_name;
return ret;
const char *storage_name;
&storage_name);
NULL);
static struct dsync_worker_msg_iter *
unsigned int mailbox_count)
for (i = 0; i < mailbox_count; i++) {
unsigned int count;
return FALSE;
return TRUE;
i_unreached();
return FALSE;
T_BEGIN {
} T_END;
unsigned int *mailbox_idx_r,
const char *guid;
return ret;
char *dest_name, *p;
else if (*p == src_sep)
*p = dest_sep;
return dest_name;
char *output, *p;
*p = alt_char;
return output;
char *output, *p;
if (!i_isalnum(*p))
*p = alt_char;
return output;
bool creating)
if (creating) {
return name;
static struct mailbox *
const char *name;
return NULL;
const char *errstr;
switch (error) {
case MAIL_ERROR_EXISTS:
case MAIL_ERROR_NOTPOSSIBLE:
const char *errstr;
&error);
const char *new_name;
int ret;
if (ret != 0) {
NULL);
const char *storage_name;
const char *newname;
unsigned int i, n, expected_count;
return FALSE;
return i == expected_count;
if (selected)
NULL));
if (selected)
unsigned int count;
int ret;
if (ret == 0) {
void *context)
unsigned int count;
if (count == 0)
worker);