void dsync_brain_send_mailbox_tree(struct dsync_brain *brain) { struct dsync_mailbox_node *node; enum dsync_ibc_send_ret ret; const char *full_name; char sep[2]; sep[0] = brain->hierarchy_sep; sep[1] = '\0'; while (dsync_mailbox_tree_iter_next(brain->local_tree_iter, &full_name, &node)) { T_BEGIN { const char *const *parts; if (brain->debug) { i_debug("brain %c: Local mailbox tree: %s %s", brain->master_brain ? 'M' : 'S', full_name, dsync_mailbox_node_to_string(node)); } parts = t_strsplit(full_name, sep); ret = dsync_ibc_send_mailbox_tree_node(brain->ibc, parts, node); } T_END; if (ret == DSYNC_IBC_SEND_RET_FULL) return; } dsync_mailbox_tree_iter_deinit(&brain->local_tree_iter); dsync_ibc_send_end_of_list(brain->ibc, DSYNC_IBC_EOL_MAILBOX_TREE); brain->state = DSYNC_STATE_SEND_MAILBOX_TREE_DELETES; }
static int dsync_brain_try_next_mailbox(struct dsync_brain *brain, struct mailbox **box_r, struct dsync_mailbox *dsync_box_r) { enum mailbox_flags flags = 0; struct dsync_mailbox dsync_box; struct mailbox *box; struct dsync_mailbox_node *node; const char *vname = NULL; bool synced = FALSE; int ret; *box_r = NULL; while (dsync_mailbox_tree_iter_next(brain->local_tree_iter, &vname, &node)) { if (node->existence == DSYNC_MAILBOX_NODE_EXISTS && !guid_128_is_empty(node->mailbox_guid)) break; vname = NULL; } if (vname == NULL) { /* no more mailboxes */ dsync_mailbox_tree_iter_deinit(&brain->local_tree_iter); return -1; } if (brain->backup_send) { /* make sure mailbox isn't modified */ flags |= MAILBOX_FLAG_READONLY; } box = mailbox_alloc(node->ns->list, vname, flags); for (;;) { if ((ret = dsync_box_get(box, &dsync_box)) <= 0) { if (ret < 0) brain->failed = TRUE; mailbox_free(&box); return ret; } /* if mailbox's last_common_* state equals the current state, we can skip the mailbox */ if (!dsync_brain_has_mailbox_state_changed(brain, &dsync_box)) { mailbox_free(&box); return 0; } if (synced) { /* ok, the mailbox really changed */ break; } /* mailbox appears to have changed. do a full sync here and get the state again */ if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { i_error("Can't sync mailbox %s: %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); brain->failed = TRUE; mailbox_free(&box); return -1; } synced = TRUE; } *box_r = box; *dsync_box_r = dsync_box; return 1; }