imapc-sync.c revision 90355e35d1139e446a99733986a9181bd7f05dd4
/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "str.h"
#include "imap-util.h"
#include "mail-cache.h"
#include "mail-index-modseq.h"
#include "index-sync-private.h"
#include "imapc-client.h"
#include "imapc-msgmap.h"
#include "imapc-list.h"
#include "imapc-storage.h"
#include "imapc-sync.h"
struct imapc_sync_command {
struct imapc_sync_context *ctx;
char *cmd_str;
bool ignore_no;
};
void *context)
{
;
/* maybe the message was expunged already.
some servers fail STOREs with NO in such situation. */
/* the disconnection is already logged, don't flood
the logs unnecessarily */
} else {
"imapc: Sync command '%s' failed: %s",
}
if (--ctx->sync_command_count == 0)
}
static struct imapc_command *
bool ignore_no)
{
struct imapc_sync_command *sync_cmd;
struct imapc_command *cmd;
return cmd;
}
static struct imapc_command *
{
}
static struct imapc_command *
{
}
static void
{
const struct mail_index_record *rec;
const char *cmd;
/* if any of them has a missing \Deleted flag,
just add it to all of them. */
break;
}
}
}
const struct mail_index_sync_rec *sync_rec)
{
}
if (sync_rec->remove_flags != 0) {
str_truncate(str, 0);
}
}
static void
const struct mail_index_sync_rec *sync_rec)
{
const char *const *kw_p;
char change_char;
change_char = '+';
break;
change_char = '-';
break;
default:
i_unreached();
}
}
{
enum imapc_capability caps;
return;
if ((caps & IMAPC_CAPABILITY_UIDPLUS) == 0) {
/* just expunge everything */
return;
}
/* build a list of UIDs to expunge */
}
{
if (mbox->sync_next_lseq == 0)
return;
/* if we haven't seen FETCH reply for some messages at the end of
mailbox they've been externally expunged. */
/* another process already added new messages to index
that our IMAP connection hasn't seen yet */
break;
}
}
mbox->sync_next_lseq = 0;
mbox->sync_next_rseq = 0;
}
{
const struct mail_index_header *hdr;
mbox->sync_uid_validity != 0) {
if (hdr->uid_validity != 0) {
/* uidvalidity changed, reset the entire mailbox */
}
}
}
{
const struct mail_index_header *hdr;
}
}
{
}
static void
{
struct imapc_msgmap *msgmap =
else
else
/* message exists in index and in remote server */
/* message exists in index but not in remote server */
/* the message was added to index by another
imapc session, and it's not visible yet
in this session */
break;
}
/* it's already expunged and we should have marked it */
lseq++;
} else {
/* message doesn't exist in index, but exists in
remote server */
/* the message hasn't been yet added to index */
break;
}
/* another imapc session expunged it =>
NOOP should send us an EXPUNGE event */
if (!nooped) {
return;
}
/* already nooped => index is corrupted */
"Expunged message uid=%u reappeared", ruid);
rseq++;
}
}
}
static void
{
}
enum mailbox_info_flags flags;
if (first_uid == 1 &&
/* these can be efficiently fetched among flags and
stored into cache */
}
/* do this only for the \All mailbox */
(flags & MAILBOX_SPECIALUSE_ALL) != 0)
}
struct imapc_command *cmd;
}
}
{
struct mail_index_sync_rec sync_rec;
/* already expunged, nothing to do. */
break;
break;
break;
}
} T_END;
if (!mbox->initial_sync_done) {
/* with initial syncing we're fetching all messages' flags and
expunge mails from local index that no longer exist on
remote server */
}
if (mbox->sync_fetch_first_uid != 0) {
/* we'll resync existing messages' flags and add new messages.
adding new messages requires sync locking to avoid
duplicates. */
mbox->sync_fetch_first_uid = 0;
}
while (ctx->sync_command_count > 0)
/* add uidnext & highestmodseq after all appends */
}
}
{
/* we got disconnected while syncing. need to
re-fetch everything */
}
static int
{
struct imapc_sync_context *ctx;
int ret;
if (!force)
if (ret <= 0) {
if (ret < 0)
return ret;
}
return 0;
}
{
bool changes;
if (ret == 0) {
ret = -1;
}
} else {
}
"gmail-pop3 search not successful");
ret = -1;
}
/* this is done simply to commit delayed expunges if there are any
(has to be done after sync is committed) */
return ret;
}
{
struct imapc_sync_context *sync_ctx;
/* we're only saving mails here - no syncing actually wanted */
return 0;
}
return -1;
return 0;
if (imapc_sync_finish(&sync_ctx) < 0)
return -1;
return 0;
}
static void
{
enum imapc_capability capabilities;
if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0 ||
(flags & MAILBOX_SYNC_FLAG_FULL_READ) != 0) {
/* do NOOP to make sure we have the latest changes before
starting sync. this is necessary either because se don't
support IDLE at all, or because we want to be sure that we
have the latest changes (IDLE is started with a small delay,
so we might not actually even be in IDLE right not) */
}
}
struct mailbox_sync_context *
{
bool changes;
int ret = 0;
if (!list->refreshed_mailboxes &&
}
if (mailbox_open(box) < 0)
ret = -1;
}
if (ret == 0)
ret = -1;
ret == 0)
}
struct mailbox_sync_status *status_r)
{
int ret;
return ret;
return ret;
}