add ExpireUnread option
This commit is contained in:
parent
f586c0bee5
commit
8d5bd62537
|
@ -233,6 +233,8 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf )
|
|||
conf->use_internal_date = parse_bool( cfile );
|
||||
else if (!strcasecmp( "MaxMessages", cfile->cmd ))
|
||||
conf->max_messages = parse_int( cfile );
|
||||
else if (!strcasecmp( "ExpireUnread", cfile->cmd ))
|
||||
conf->expire_unread = parse_bool( cfile );
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -347,6 +349,7 @@ load_config( const char *where, int pseudo )
|
|||
cfile.err = 0;
|
||||
|
||||
gcops = 0;
|
||||
global_conf.expire_unread = -1;
|
||||
reloop:
|
||||
while (getcline( &cfile )) {
|
||||
if (!cfile.cmd)
|
||||
|
@ -369,6 +372,7 @@ load_config( const char *where, int pseudo )
|
|||
channel = nfcalloc( sizeof(*channel) );
|
||||
channel->name = nfstrdup( cfile.val );
|
||||
channel->max_messages = global_conf.max_messages;
|
||||
channel->expire_unread = global_conf.expire_unread;
|
||||
channel->use_internal_date = global_conf.use_internal_date;
|
||||
cops = 0;
|
||||
max_size = -1;
|
||||
|
|
|
@ -167,6 +167,7 @@ typedef struct channel_conf {
|
|||
string_list_t *patterns;
|
||||
int ops[2];
|
||||
unsigned max_messages; /* for slave only */
|
||||
signed char expire_unread;
|
||||
char use_internal_date;
|
||||
} channel_conf_t;
|
||||
|
||||
|
|
14
src/mbsync.1
14
src/mbsync.1
|
@ -400,12 +400,22 @@ This is useful for mailboxes where you keep a complete archive on the server,
|
|||
but want to mirror only the last messages (for instance, for mailing lists).
|
||||
The messages that were the first to arrive in the mailbox (independently of
|
||||
the actual date of the message) will be deleted first.
|
||||
Messages that are flagged (marked as important) and unread messages will not
|
||||
be automatically deleted.
|
||||
Messages that are flagged (marked as important) and (by default) unread
|
||||
messages will not be automatically deleted.
|
||||
If \fIcount\fR is 0, the maximum number of messages is \fBunlimited\fR
|
||||
(Default: \fI0\fR).
|
||||
..
|
||||
.TP
|
||||
\fBExpireUnread\fR \fIyes\fR|\fIno\fR
|
||||
Selects whether unread messages should be affected by \fBMaxMessages\fR.
|
||||
Normally, unread messages are considered important and thus never expired.
|
||||
This ensures that you never miss new messages even after an extended absence.
|
||||
However, if your archive contains large amounts of unread messages by design,
|
||||
treating them as important would practically defeat \fBMaxMessages\fR. In this
|
||||
case you need to enable this option.
|
||||
(Default: \fIno\fR).
|
||||
..
|
||||
.TP
|
||||
\fBSync\fR {\fINone\fR|[\fIPull\fR] [\fIPush\fR] [\fINew\fR] [\fIReNew\fR] [\fIDelete\fR] [\fIFlags\fR]|\fIAll\fR}
|
||||
Select the synchronization operation(s) to perform:
|
||||
.br
|
||||
|
|
|
@ -191,6 +191,18 @@ my @X31 = (
|
|||
);
|
||||
test("max messages", \@x30, \@X31, @O31);
|
||||
|
||||
my @O32 = ("", "", "MaxMessages 3\nExpireUnread yes\n");
|
||||
#show("30", "32", "32");
|
||||
my @X32 = (
|
||||
[ 6,
|
||||
1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ],
|
||||
[ 4,
|
||||
1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ],
|
||||
[ 6, 1, 0,
|
||||
1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ],
|
||||
);
|
||||
test("max messages vs. unread", \@x30, \@X32, @O32);
|
||||
|
||||
my @x50 = (
|
||||
[ 6,
|
||||
1, 1, "FS", 2, 2, "FS", 3, 3, "S", 4, 4, "", 5, 5, "", 6, 6, "" ],
|
||||
|
|
13
src/sync.c
13
src/sync.c
|
@ -1370,6 +1370,7 @@ box_loaded( int sts, void *aux )
|
|||
}
|
||||
todel = alive - svars->chan->max_messages;
|
||||
debug( "%d alive messages, %d excess - expiring\n", alive, todel );
|
||||
alive = 0;
|
||||
for (tmsg = svars->ctx[S]->msgs; tmsg; tmsg = tmsg->next) {
|
||||
if (tmsg->status & M_DEAD)
|
||||
continue;
|
||||
|
@ -1381,7 +1382,7 @@ box_loaded( int sts, void *aux )
|
|||
nflags = (tmsg->flags | srec->aflags[S]) & ~srec->dflags[S];
|
||||
if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE|S_EXPIRED))) {
|
||||
/* The message is not deleted, or is already (being) expired. */
|
||||
if ((nflags & F_FLAGGED) || !(nflags & F_SEEN)) {
|
||||
if ((nflags & F_FLAGGED) || !((nflags & F_SEEN) || ((void)(todel > 0 && alive++), svars->chan->expire_unread > 0))) {
|
||||
/* Important messages are always kept. */
|
||||
debug( " old pair(%d,%d) important\n", srec->uid[M], srec->uid[S] );
|
||||
todel--;
|
||||
|
@ -1400,7 +1401,7 @@ box_loaded( int sts, void *aux )
|
|||
if ((srec = tmsg->srec) && srec->tuid[0]) {
|
||||
nflags = tmsg->flags;
|
||||
if (!(nflags & F_DELETED)) {
|
||||
if ((nflags & F_FLAGGED) || !(nflags & F_SEEN)) {
|
||||
if ((nflags & F_FLAGGED) || !((nflags & F_SEEN) || ((void)(todel > 0 && alive++), svars->chan->expire_unread > 0))) {
|
||||
/* Important messages are always fetched. */
|
||||
debug( " new pair(%d,%d) important\n", srec->uid[M], srec->uid[S] );
|
||||
todel--;
|
||||
|
@ -1415,6 +1416,14 @@ box_loaded( int sts, void *aux )
|
|||
}
|
||||
}
|
||||
debug( "%d excess messages remain\n", todel );
|
||||
if (svars->chan->expire_unread < 0 && (unsigned)alive * 2 > svars->chan->max_messages) {
|
||||
error( "%s: %d unread messages in excess of MaxMessages (%d).\n"
|
||||
"Please set ExpireUnread to decide outcome. Skipping mailbox.\n",
|
||||
svars->ctx[S]->orig_name, alive, svars->chan->max_messages );
|
||||
svars->ret |= SYNC_FAIL;
|
||||
cancel_sync( svars );
|
||||
return;
|
||||
}
|
||||
for (srec = svars->srecs; srec; srec = srec->next) {
|
||||
if (srec->status & S_DEAD)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue
Block a user