/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "hash.h"
#include "mail-index-modseq.h"
#include "mail-storage-private.h"
#include "dsync-mail.h"
#include "dsync-mailbox.h"
#include "dsync-transaction-log-scan.h"
struct dsync_transaction_log_scan {
bool returned_all_changes;
};
static bool ATTR_NOWARN_UNUSED_RESULT
enum dsync_mail_change_type type,
struct dsync_mail_change **change_r)
{
const char *orig_guid;
return FALSE;
/* first change for this UID */
} else if (type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) {
/* expunge overrides flag changes */
/* already expunged, this change doesn't matter */
return FALSE;
} else {
/* another flag update */
}
return TRUE;
}
static void
const struct mail_transaction_header *hdr)
{
/* this is simply a request for expunge */
return;
}
&change);
}
}
}
static bool
{
/* this is simply a request for expunge */
return FALSE;
}
&change);
return TRUE;
}
}
return FALSE;
}
static void
const struct mail_transaction_header *hdr)
{
bool external;
/* expunge request that hasn't been actually done yet.
we check non-external ones because they might have
the GUID while external ones don't. */
continue;
}
&change) &&
} T_END;
}
}
static bool
{
/* we're assuming UID is already known to be expunged */
continue;
&change))
i_unreached();
} T_END;
return TRUE;
}
return FALSE;
}
static void
const struct mail_transaction_header *hdr)
{
&change)) {
}
}
}
}
static void
const struct mail_transaction_header *hdr)
{
&change))
continue;
}
}
}
static void
{
const char *const *changes;
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
}
}
static void
const struct mail_transaction_header *hdr)
{
unsigned int uids_offset;
if ((uids_offset % 4) != 0)
switch (rec->modify_type) {
case MODIFY_ADD:
break;
case MODIFY_REMOVE:
break;
default:
i_unreached();
}
&change))
continue;
} else {
}
}
}
}
static void
{
/* update message's modseq, possibly by creating an empty flag change */
/* highestmodseq update */
continue;
}
&change))
continue;
if (!pvt_scan) {
} else {
}
}
}
static void
{
}
}
static void
const void *data,
const struct mail_transaction_header *hdr,
{
unsigned int i;
}
}
static int
{
const char *reason;
bool reset;
int ret;
if (modseq != 0 &&
&log_seq, &log_offset)) {
/* scan the view only up to end of the current view.
if there are more changes, we don't care about them until
the next sync. */
if (ret != 0)
return ret;
}
/* return everything we've got (until the end of the view) */
if (!pvt_scan)
if (mail_transaction_log_view_set_all(log_view) < 0)
return -1;
}
if (ret == 0) {
/* we shouldn't get here. _view_set_all() already
reserved all the log files, the _view_set() only
removed unwanted ones. */
i_error("%s: Couldn't set transaction log view (seq %u..%u): %s",
ret = -1;
}
if (ret < 0)
return -1;
if (modseq != 0) {
/* we didn't see all the changes that we wanted to */
return 0;
}
return 1;
}
static int
{
const void *data;
int ret;
return -1;
}
/* read the log only up to current position in view */
&file_offset);
&file_offset);
break;
/* ignore changes done by dsync, unless we can get
expunged message's GUID from it */
continue;
}
case MAIL_TRANSACTION_EXPUNGE:
if (!pvt_scan)
break;
if (!pvt_scan)
break;
break;
break;
T_BEGIN {
} T_END;
break;
break;
break;
}
}
if (!pvt_scan) {
}
return ret;
}
static int
const struct dsync_mailbox_attribute *attr2)
{
return -1;
return 1;
}
static unsigned int
{
}
struct mail_index_view *pvt_view,
struct dsync_transaction_log_scan **scan_r,
bool *pvt_too_old_r)
{
*pvt_too_old_r = FALSE;
10240);
return -1;
return -1;
if (ret2 == 0) {
ret = 0;
*pvt_too_old_r = TRUE;
}
}
return ret;
}
{
}
{
return scan->attr_changes;
}
bool
{
return scan->returned_all_changes;
}
struct dsync_mail_change *
{
const void *data;
const char *reason;
while (!found &&
case MAIL_TRANSACTION_EXPUNGE:
break;
break;
}
}
}
}
{
}