commit 8d5bd62537ee8c5f68b311fe8c3d8058c522776c
Author: Oswald Buddenhagen <[email protected]>
Date: Sun Nov 24 20:26:33 2013 +0100
add ExpireUnread option
src/config.c | 4 ++++
src/isync.h | 1 +
src/mbsync.1 | 14 ++++++++++++--
src/run-tests.pl | 12 ++++++++++++
src/sync.c | 13 +++++++++++--
5 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/config.c b/src/config.c
index c103c97..5fa665f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -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;
diff --git a/src/isync.h b/src/isync.h
index b67a969..0bad436 100644
--- a/src/isync.h
+++ b/src/isync.h
@@ -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;
diff --git a/src/mbsync.1 b/src/mbsync.1
index 7813c6a..10cc81b 100644
--- a/src/mbsync.1
+++ b/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
diff --git a/src/run-tests.pl b/src/run-tests.pl
index 7f1ec8b..214af62 100755
--- a/src/run-tests.pl
+++ b/src/run-tests.pl
@@ -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, "" ],
diff --git a/src/sync.c b/src/sync.c
index 554843d..af7188e 100644
--- a/src/sync.c
+++ b/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;
------------------------------------------------------------------------------
Sponsored by Intel(R) XDK
Develop, test and display web and hybrid apps with a single code base.
Download it for free now!
http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel