imap-sync.c revision 3419b088ffe531799bdb47b3ff3fce85c8b7569a
/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "str.h"
#include "ostream.h"
#include "mail-storage.h"
#include "imap-util.h"
#include "imap-sync.h"
#include "commands.h"
struct client_sync_context {
/* if multiple commands are in progress, we may need to wait for them
to finish before syncing mailbox. */
unsigned int counter;
enum mailbox_sync_flags flags;
enum imap_sync_flags imap_flags;
const char *tagline;
};
struct imap_sync_context {
enum imap_sync_flags imap_flags;
struct mailbox_transaction_context *t;
struct mailbox_sync_context *sync_ctx;
struct mailbox_sync_rec sync_rec;
unsigned int messages_count;
unsigned int failed:1;
unsigned int no_newmail:1;
};
struct imap_sync_context *
{
struct imap_sync_context *ctx;
return ctx;
}
{
struct mailbox_status status;
int ret;
return -1;
}
/* most clients would get confused by this. disconnect them. */
"Mailbox UIDVALIDITY changed");
}
if (!ctx->no_newmail) {
i_panic("Message count decreased");
}
!ctx->no_newmail) {
}
}
return ret;
}
{
enum mail_flags flags;
const char *const *keywords;
if ((flags & MAIL_DELETED) != 0)
str_truncate(str, 0);
}
{
int ret = 1;
for (;;) {
/* get next one */
/* finished */
ret = 1;
break;
}
}
/* don't send change notifications of messages we
haven't even announced to client yet */
continue;
}
}
case MAILBOX_SYNC_TYPE_FLAGS:
ret = 1;
if (ret <= 0)
break;
}
break;
ret = 1;
if (ret <= 0)
break;
str_truncate(str, 0);
}
/* update only after we're finished, so that
the seq2 > messages_count check above
doesn't break */
ctx->messages_count -=
}
break;
}
if (ret <= 0) {
/* failure / buffer full */
break;
}
}
return ret;
}
{
else {
return TRUE;
}
}
{
int ret;
return FALSE;
if (ret < 0)
if (imap_sync_deinit(ctx) < 0) {
}
/* finish all commands that waited for this sync */
if (cmd_finish_sync(cmd))
}
}
return cmd_finish_sync(sync_cmd);
}
enum mailbox_sync_flags *flags_r,
enum imap_sync_flags *imap_flags_r)
{
struct client_command_context *cmd;
*flags_r = 0;
*imap_flags_r = 0;
fast_count++;
count++;
}
}
if (fast_count != count)
MAILBOX_SYNC_FLAG_FIX_INCONSISTENT)) == 0);
}
{
struct imap_sync_context *ctx;
enum mailbox_sync_flags flags;
enum imap_sync_flags imap_flags;
bool no_newmail;
/* there may be multiple commands waiting. use their combined flags */
client->sync_counter++;
(imap_flags & IMAP_SYNC_FLAG_SAFE) == 0;
if (no_newmail) {
/* expunges might break the client just as badly as new mail
notifications. */
}
/* handle the syncing using sync_cmd. it doesn't actually matter which
one of the pending commands it is. */
if (!cmd_sync_continue(sync_cmd)) {
return FALSE;
}
(void)cmd_sync_delayed(client);
return TRUE;
}
static bool
{
return TRUE;
/* no mailbox selected, no point in delaying the sync */
return TRUE;
}
return FALSE;
}
{
}
enum mailbox_sync_flags flags,
enum imap_sync_flags imap_flags,
{
}
{
if (cmd_finish_sync(cmd)) {
}
}
}
return ret;
}
{
/* wait until we can send output to client */
return FALSE;
}
/* wait until mailbox can be synced */
return cmd_sync_drop_fast(client);
}
/* separate syncs that can send expunges from those that can't */
if (first_nonexpunge == NULL)
} else {
if (first_expunge == NULL)
first_expunge = cmd;
}
}
}
/* sync expunges after nonexpunges */
}
}
return cmd_sync_drop_fast(client);
return cmd_sync_client(cmd);
}