/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "crc32.h"
#include "numpack.h"
#include "net.h"
#include "ostream.h"
#include "str.h"
#include "str-sanitize.h"
#include "imap-util.h"
#include "mail-search-build.h"
#include "mail-storage-private.h"
#include "mailbox-recent-flags.h"
#include "imap-client.h"
#include "imap-fetch.h"
#include "imap-search-args.h"
#include "imap-state.h"
enum imap_state_type_public {
};
enum imap_state_type_internal {
};
enum imap_state_feature {
};
struct mailbox_import_state {
const char *vname;
bool examined;
};
static void
{
unsigned int i, count;
next_uid = 1;
for (i = 0; i < count; i++) {
} else {
}
}
}
static int
{
return -1;
next_uid = 1;
for (i = 0; i < count; i++) {
return -1;
if ((num & 1) == 0) {
} else {
return -1;
}
}
return 0;
}
const char **error_r)
{
/* the only IMAP command we allow running is IDLE or X-STATE */
*error_r = "Multiple commands in progress";
return 0;
}
/* this would require saving the seq <-> uid mapping
and restore it on import. quite a lot of trouble if
messages have been expunged in the mean time. */
*error_r = "Non-IDLE connections not supported currently";
return 0;
}
}
const char **error_r)
{
*error_r = "Multiple commands in progress";
return 0;
}
}
static int
{
while (size > 0) {
if (ret <= 0) {
return ret < 0 ? -1 : 0;
}
}
return 1;
}
const char **error_r)
{
}
const char **error_r)
{
}
static int
const char **error_r)
{
"unhibernate imap_state_export_mailbox_mails");
}
if (mailbox_search_deinit(&search_ctx) < 0) {
ret = -1;
}
(void)mailbox_transaction_commit(&trans);
return ret;
}
static uint32_t
{
const char *const *strp;
return crc;
}
static int
{
&status);
if (status.nonpermanent_modseqs) {
*error_r = "Nonpermanent modseqs";
return 0;
}
/* if the selected mailbox can't have a GUID, fail silently */
}
else
/* keywords count + CRC32 should be enough to figure out if it
needs to be resent */
/* we're now basically done, but just in case there's a bug add a
checksum of the currently existing UIDs and verify it when
importing. this also writes the list of recent UIDs. */
}
{
int ret;
/* these could be tricky */
*error_r = "CONTEXT=SEARCH updates not supported currently";
return 0;
}
/* FIXME: this really should be supported. also IDLE wouldn't
be needed if NOTIFY allows sending EXPUNGEs to selected
mailbox. */
*error_r = "NOTIFY not supported currently";
return 0;
}
if (ret <= 0)
return ret;
}
/* IMAP features */
if (client->enabled_features != 0) {
MAILBOX_FEATURE_QRESYNC)) == 0);
}
if (internal) {
if (client->tls_compression)
}
/* IMAP SEARCHRES extension */
}
return 1;
}
static int
const char **str_r)
{
const unsigned char *p;
if (p == NULL)
return -1;
*data = p + 1;
return 0;
}
static int
const struct mailbox_import_state *state,
unsigned int *expunge_count_r,
const char **error_r)
{
unsigned int i, expunge_count, n = 0;
int ret = 0;
*expunge_count_r = 0;
/* the mailbox was empty originally - there couldn't be any
pending expunges. */
return 0;
}
*error_r = "Invalid UIDNEXT";
return -1;
}
/* get all the message UIDs expunged since the last known modseq */
&uids_filter, &expunged_uids)) {
"Couldn't get recently expunged UIDs "
return -1;
}
"unhibernate import_send_expunges");
/* find sequence numbers for the expunged UIDs */
seq++; n++;
sizeof(expunged_uid));
}
break;
break;
}
seq++; n++;
sizeof(expunged_uid));
}
if (mailbox_search_deinit(&search_ctx) < 0) {
ret = -1;
"handling expunges (%u != %u)",
ret = -1;
}
(void)mailbox_transaction_commit(&trans);
if (ret < 0)
return -1;
"handling expunges (%u < %u)",
return -1;
}
return -1;
}
for (i = expunge_count; i > 0; i--) {
str_truncate(str, 0);
}
} else {
}
return 0;
}
static int
const struct mailbox_import_state *state,
unsigned int *flag_change_count_r)
{
int ret;
*flag_change_count_r = 0;
return 0;
pool_unref(&pool);
}
/* FIXME: ideally do this asynchronously.. */
while (imap_fetch_more_no_lock_update(fetch_ctx) == 0) ;
return ret;
}
static ssize_t
struct mailbox_import_state *state_r,
const char **error_r)
{
/* vname */
*error_r = "Mailbox state truncated at name";
return 0;
}
/* GUID */
*error_r = "Mailbox state truncated at GUID";
return 0;
}
p += sizeof(state_r->mailbox_guid);
*error_r = "Empty GUID";
return 0;
}
/* EXAMINEd vs SELECTed */
if (p == end) {
*error_r = "Mailbox state truncated at examined-flag";
return 0;
}
p++;
/* mailbox state */
*error_r = "Mailbox state truncated";
return 0;
}
if (state_r->uidvalidity == 0) {
*error_r = "Empty UIDVALIDITY";
return 0;
}
*error_r = "Empty UIDNEXT";
return 0;
}
return p - data;
}
static int
const struct mailbox_import_state *state,
const char **error_r)
{
int ret = 0;
*error_r = "Namespace not found for mailbox";
return -1;
}
else
if (mailbox_open(box) < 0) {
mailbox_free(&box);
return -1;
}
if (client->enabled_features != 0)
mailbox_free(&box);
return -1;
}
/* verify that this still looks like the same mailbox */
mailbox_free(&box);
return -1;
}
mailbox_free(&box);
return -1;
}
mailbox_free(&box);
return -1;
}
mailbox_free(&box);
return -1;
}
mailbox_free(&box);
return -1;
}
return -1;
return -1;
}
}
}
/* new messages arrived */
}
/* no changes to keywords */
} else {
}
*error_r = "Couldn't send flag changes";
return -1;
}
}
i_debug("Unhibernation sync: %u expunges, %u new messages, %u flag changes, %"PRIu64" modseq changes",
return 0;
}
static ssize_t
{
*error_r = "Duplicate mailbox state";
return 0;
}
if (ret <= 0) {
return ret;
}
return -1;
}
return ret;
}
static ssize_t
{
size_t i = 0;
for (i = 0; i < size; i++) {
if (data[i] == '\0')
return i+1;
switch (feature) {
break;
break;
default:
"Unknown feature '%c'", feature);
return 0;
}
}
*error_r = "Non-terminated features list";
return 0;
}
static ssize_t
{
const unsigned char *p = data;
*error_r = "Invalid SEARCHRES seq-range";
return 0;
}
return p - data;
}
static ssize_t
const unsigned char *data ATTR_UNUSED,
const char **error_r ATTR_UNUSED)
{
return 0;
}
static ssize_t
const unsigned char *data ATTR_UNUSED,
const char **error_r ATTR_UNUSED)
{
return 0;
}
{
if (client->state_import_idle_continue) {
/* IDLE command continues */
if (command_exec(cmd)) {
/* IDLE terminated because of an external change, but
DONE was already buffered */
} else {
}
} else {
/* we're finishing IDLE command */
"%s %s Idle completed.", tag,
}
}
static struct {
} imap_states_public[] = {
};
static struct {
} imap_states_internal[] = {
};
static ssize_t
{
unsigned int i;
for (i = 0; i < N_ELEMENTS(imap_states_public); i++) {
ret = imap_states_public[i].
}
}
return -2;
}
static ssize_t
{
unsigned int i;
for (i = 0; i < N_ELEMENTS(imap_states_internal); i++) {
ret = imap_states_internal[i].
}
}
return -2;
}
const char **error_r)
{
const unsigned char *p;
if (p == NULL)
return 0;
}
pos = 5;
}
if (ret == -2) {
}
return ret < 0 ? -1 : 0;
}
}
return pos;
}