#include <ctype.h>
#include <sys/wait.h>
-#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:I:l:m:n:NO:Pr:Rs:t:T:Ux:"
+#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:I:l:m:n:NO:Pr:Rs:t:e:T:Ux:"
#define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30
/* The broken_char is mainly set to get a proper error message when trying to
convert a mailbox with a name that can't be used properly translated between
ARRAY_TYPE(const_string) exclude_mailboxes;
ARRAY_TYPE(const_string) namespace_prefixes;
time_t sync_since_timestamp;
+ time_t sync_until_timestamp;
uoff_t sync_max_size;
unsigned int io_timeout_secs;
"%s ", net_ip2addr(&_ctx->cur_client_ip));
}
set.sync_since_timestamp = ctx->sync_since_timestamp;
+ set.sync_until_timestamp = ctx->sync_until_timestamp;
+
+ if (set.sync_since_timestamp > 0 && set.sync_until_timestamp > 0 &&
+ set.sync_since_timestamp > set.sync_until_timestamp) {
+ i_fatal("start date is later than end date");
+ }
+
set.sync_max_size = ctx->sync_max_size;
set.sync_box = ctx->mailbox;
set.sync_flag = ctx->sync_flags;
if (mail_parse_human_timestamp(optarg, &ctx->sync_since_timestamp) < 0)
i_fatal("Invalid -t parameter: %s", optarg);
break;
+ case 'e':
+ if (mail_parse_human_timestamp(optarg, &ctx->sync_until_timestamp) < 0)
+ i_fatal("Invalid -e parameter: %s", optarg);
+ break;
case 'I':
if (settings_get_size(optarg, &ctx->sync_max_size, &error) < 0)
i_fatal("Invalid -I parameter '%s': %s", optarg, error);
remote_dsync_box->highest_modseq,
remote_dsync_box->highest_pvt_modseq,
brain->sync_since_timestamp,
+ brain->sync_until_timestamp,
brain->sync_max_size,
brain->sync_flag,
import_flags);
exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS;
if (brain->no_mail_prefetch)
exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MINIMAL_DMAIL_FILL;
- if (brain->sync_since_timestamp > 0)
+ if (brain->sync_since_timestamp > 0 ||
+ brain->sync_until_timestamp > 0)
exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS;
if (brain->sync_max_size > 0)
exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_VSIZES;
const char *const *exclude_mailboxes;
enum dsync_brain_sync_type sync_type;
time_t sync_since_timestamp;
+ time_t sync_until_timestamp;
uoff_t sync_max_size;
const char *sync_flag;
char alt_char;
brain->alt_char = set->mailbox_alt_char == '\0' ? '_' :
set->mailbox_alt_char;
brain->sync_since_timestamp = set->sync_since_timestamp;
+ brain->sync_until_timestamp = set->sync_until_timestamp;
brain->sync_max_size = set->sync_max_size;
brain->sync_flag = p_strdup(brain->pool, set->sync_flag);
brain->sync_box = p_strdup(brain->pool, set->sync_box);
ibc_set.virtual_all_box = set->virtual_all_box;
ibc_set.exclude_mailboxes = set->exclude_mailboxes;
ibc_set.sync_since_timestamp = set->sync_since_timestamp;
+ ibc_set.sync_until_timestamp = set->sync_until_timestamp;
ibc_set.sync_max_size = set->sync_max_size;
ibc_set.sync_flags = set->sync_flag;
memcpy(ibc_set.sync_box_guid, set->sync_box_guid,
brain->exclude_mailboxes = ibc_set->exclude_mailboxes == NULL ? NULL :
p_strarray_dup(brain->pool, ibc_set->exclude_mailboxes);
brain->sync_since_timestamp = ibc_set->sync_since_timestamp;
+ brain->sync_until_timestamp = ibc_set->sync_until_timestamp;
brain->sync_max_size = ibc_set->sync_max_size;
brain->sync_flag = p_strdup(brain->pool, ibc_set->sync_flags);
memcpy(brain->sync_box_guid, ibc_set->sync_box_guid,
char mailbox_alt_char;
/* Sync only mails with received timestamp at least this high. */
time_t sync_since_timestamp;
+ /* Sync only mails with received timestamp less or equal than this */
+ time_t sync_until_timestamp;
/* Don't sync mails larger than this. */
uoff_t sync_max_size;
/* Sync only mails which contains / doesn't contain this flag.
memcpy(item->u.set.sync_box_guid, set->sync_box_guid,
sizeof(item->u.set.sync_box_guid));
item->u.set.sync_since_timestamp = set->sync_since_timestamp;
+ item->u.set.sync_until_timestamp = set->sync_until_timestamp;
item->u.set.sync_max_size = set->sync_max_size;
item->u.set.sync_flags = p_strdup(item->pool, set->sync_flags);
}
"debug sync_visible_namespaces exclude_mailboxes "
"send_mail_requests backup_send backup_recv lock_timeout "
"no_mail_sync no_mailbox_renames no_backup_overwrite purge_remote "
- "no_notify sync_since_timestamp sync_max_size sync_flags "
+ "no_notify sync_since_timestamp sync_max_size sync_flags sync_until_timestamp"
"virtual_all_box"
},
{ .name = "mailbox_state",
dsync_serializer_encode_add(encoder, "sync_since_timestamp",
t_strdup_printf("%ld", (long)set->sync_since_timestamp));
}
+ if (set->sync_until_timestamp > 0) {
+ dsync_serializer_encode_add(encoder, "sync_until_timestamp",
+ t_strdup_printf("%ld", (long)set->sync_since_timestamp));
+ }
if (set->sync_max_size > 0) {
dsync_serializer_encode_add(encoder, "sync_max_size",
t_strdup_printf("%llu", (unsigned long long)set->sync_max_size));
return DSYNC_IBC_RECV_RET_TRYAGAIN;
}
}
+ if (dsync_deserializer_decode_try(decoder, "sync_until_timestamp", &value)) {
+ if (str_to_time(value, &set->sync_until_timestamp) < 0 ||
+ set->sync_until_timestamp == 0) {
+ dsync_ibc_input_error(ibc, decoder,
+ "Invalid sync_until_timestamp: %s", value);
+ return DSYNC_IBC_RECV_RET_TRYAGAIN;
+ }
+ }
if (dsync_deserializer_decode_try(decoder, "sync_max_size", &value)) {
if (str_to_uoff(value, &set->sync_max_size) < 0 ||
set->sync_max_size == 0) {
const char *const *exclude_mailboxes;
/* Sync only mails with received timestamp at least this high. */
time_t sync_since_timestamp;
+ /* Sync only mails with received timestamp less or equal than this */
+ time_t sync_until_timestamp;
/* Don't sync mails larger than this. */
uoff_t sync_max_size;
/* Sync only mails with specified flags. */
/* +add, -remove, =final, &add_and_final. */
ARRAY_TYPE(const_string) keyword_changes;
- /* Received timestamp for saves, if brain.sync_since_timestamp is set */
+ /* Received timestamp for saves, if brain.sync_since/until_timestamp is set */
time_t received_timestamp;
/* Mail's size for saves if brain.sync_max_size is set,
(uoff_t)-1 otherwise. */
uint32_t remote_first_recent_uid;
uint64_t remote_highest_modseq, remote_highest_pvt_modseq;
time_t sync_since_timestamp;
+ time_t sync_until_timestamp;
uoff_t sync_max_size;
enum mailbox_transaction_flags transaction_flags;
unsigned int hdr_hash_version;
uint32_t remote_first_recent_uid,
uint64_t remote_highest_modseq,
uint64_t remote_highest_pvt_modseq,
- time_t sync_since_timestamp, uoff_t sync_max_size,
+ time_t sync_since_timestamp,
+ time_t sync_until_timestamp,
+ uoff_t sync_max_size,
const char *sync_flag,
enum dsync_mailbox_import_flags flags)
{
importer->remote_highest_modseq = remote_highest_modseq;
importer->remote_highest_pvt_modseq = remote_highest_pvt_modseq;
importer->sync_since_timestamp = sync_since_timestamp;
+ importer->sync_until_timestamp = sync_until_timestamp;
importer->sync_max_size = sync_max_size;
importer->stateful_import = importer->last_common_uid_found;
if (sync_flag != NULL) {
return FALSE;
}
}
+ if (importer->sync_until_timestamp > 0) {
+ i_assert(change->received_timestamp > 0);
+ if (change->received_timestamp > importer->sync_until_timestamp) {
+ /* mail has too new timestamp - skip it */
+ *result_r = "Ignoring missing local mail with too new timestamp";
+ return FALSE;
+ }
+ }
if (importer->sync_max_size > 0) {
i_assert(change->virtual_size != (uoff_t)-1);
if (change->virtual_size < importer->sync_max_size) {
int ret;
i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE ||
- ((change->received_timestamp > 0 || importer->sync_since_timestamp == 0) &&
+ ((change->received_timestamp > 0 ||
+ (importer->sync_since_timestamp == 0 &&
+ importer->sync_until_timestamp == 0)) &&
(change->virtual_size != (uoff_t)-1 || importer->sync_max_size == 0)));
/* try to find the matching local mail */
uint32_t remote_first_recent_uid,
uint64_t remote_highest_modseq,
uint64_t remote_highest_pvt_modseq,
- time_t sync_since_timestamp, uoff_t sync_max_size,
+ time_t sync_since_timestamp,
+ time_t sync_until_timestamp,
+ uoff_t sync_max_size,
const char *sync_flag,
enum dsync_mailbox_import_flags flags);
int dsync_mailbox_import_attribute(struct dsync_mailbox_importer *importer,