Browse Source

fix mixing MaxMessages with MaxSize

this is actually a useful combination for resource-constrained devices.
wip/maildir-path-under-inbox
Oswald Buddenhagen 3 years ago
parent
commit
8f39d06015
  1. 2
      NEWS
  2. 125
      src/run-tests.pl
  3. 26
      src/sync.c

2
NEWS

@ -9,6 +9,8 @@ is now the file's containing directory.
Placeholders will be now created for messages exceeding MaxSize even if Placeholders will be now created for messages exceeding MaxSize even if
they are flagged on the source side. they are flagged on the source side.
MaxMessages and MaxSize can be used together now.
The unfiltered list of mailboxes in each Store can be printed now. The unfiltered list of mailboxes in each Store can be printed now.
A proper summary is now printed prior to exiting. A proper summary is now printed prior to exiting.

125
src/run-tests.pl

@ -1313,6 +1313,131 @@ my @X38 = (
); );
test("max messages + expunge", \@x38, \@X38, \@O38); test("max messages + expunge", \@x38, \@X38, \@O38);
# Expiration with size restriction tests
my @x40 = (
P, 0, P,
A, "**", "*>", "*?",
B, "**", "*>", "*S?",
C, "**", "*>S", "*S?",
D, "*S*", "*>S", "*S?",
E, "*S*", "*>", "*S?",
F, "*S*", "*>S", "*?",
G, "*S*", "*>", "*?",
H, "**", "*>S", "*?",
I, "*F*", "*>", "*?",
J, "*F*", "*>", "*S?",
K, "*F*", "*>S", "*S?",
L, "*FS*", "*>S", "*S?",
M, "*FS*", "*>", "*S?",
N, "*FS*", "*>S", "*?",
O, "*FS*", "*>", "*?",
P, "*F*", "*>S", "*?",
Q, "**", "", "",
R, "*FS*", "", "",
S, "*S*", "", "",
T, "**", "", "",
U, "*FS*", "", "",
V, "*S*", "", "",
);
my @O41 = ("", "", "MaxSize 1k\nMaxMessages 3\nExpireUnread no\n");
my @X41 = (
V, S, V,
C, "", "-S", "-S",
D, "", "+~", "+T",
E, "", "+~S", "+T",
F, "-S", "-S", "",
G, "", "+~S", "+ST",
H, "", "-S", "",
K, "", "-S", "-S",
M, "", "+S", "",
N, "-S", "-S", "",
O, "", "+S", "+S",
P, "", "-S", "",
Q, "", "*>", "*?",
R, "", "*>S", "*S?",
T, "", "*>", "*?",
U, "", "*>S", "*S?",
V, "", "*>S", "*S?",
);
test("max size without upgrade + max messages", \@x40, \@X41, \@O41);
my @x42 = (
T, Q, T,
A, "**", "*>", "*F?",
B, "**", "*>", "*FS?",
C, "**", "*>S", "*FS?",
D, "*S*", "*>S", "*FS?",
E, "*S*", "*>", "*FS?",
F, "*S*", "*>S", "*F?",
G, "*S*", "*>", "*F?",
H, "**", "*>S", "*F?",
I, "*F*", "*>", "*F?",
J, "*F*", "*>", "*FS?",
K, "*F*", "*>S", "*FS?",
L, "*FS*", "*>S", "*FS?",
M, "*FS*", "*>", "*FS?",
N, "*FS*", "*>S", "*F?",
O, "*FS*", "*>", "*F?",
P, "*F*", "*>S", "*F?",
Q, "*S", "", "",
R, "*", "*", "*",
S, "*", "*", "*",
T, "*", "*", "*",
);
my @X43 = (
T, Q, P,
A, "", ">->", "^*",
A, "&", "^", "&1+T",
B, "", ">->", "^*",
B, "&", "^", "&1+T",
C, "", ">->S", "^*",
C, "&", "^", "&1+T",
D, "", "/", "",
D, "&", "^", "&1+T",
E, "", "/", "",
E, "&", "^", "&1+T",
F, "-S", ">->S", "^*",
F, "&", "^", "&1+T",
G, "", "/", "",
G, "&", "^", "&1+T",
H, "", ">->S", "^*",
H, "&", "^", "&1+T",
I, "", ">->+F", "^F*",
I, "&", "^", "&1+T",
J, "", ">->+F", "^F*",
J, "&", "^", "&1+T",
K, "", ">->S+F", "^F*",
K, "&", "^", "&1+T",
L, "", ">->+F", "^FS*",
L, "&", "^", "&1+T",
M, "", ">->+FS", "^FS*",
M, "&", "^", "&1+T",
N, "-S", ">->S+F", "^F*",
N, "&", "^", "&1+T",
O, "", ">->+FS", "^FS*",
O, "&", "^", "&1+T",
P, "", ">->S+F", "^F*",
P, "&", "^", "&1+T",
);
test("max size with upgrade + max messages", \@x42, \@X43, \@O41);
# Test for legacy/tampered states with inaccurate maxuid tracking # Test for legacy/tampered states with inaccurate maxuid tracking
# Joined post-push & post-pull state to have just one test - # Joined post-push & post-pull state to have just one test -

26
src/sync.c

@ -799,7 +799,9 @@ box_opened2( sync_vars_t *svars, int t )
svars->any_expiring = 1; svars->any_expiring = 1;
if (svars->any_expiring) { if (svars->any_expiring) {
opts[N] |= OPEN_OLD | OPEN_FLAGS; opts[N] |= OPEN_OLD | OPEN_FLAGS;
if (chan->ops[N] & (OP_NEW | OP_RENEW)) if (any_dummies[N])
opts[F] |= OPEN_OLD | OPEN_FLAGS;
else if (chan->ops[N] & (OP_NEW | OP_RENEW))
opts[F] |= OPEN_FLAGS; opts[F] |= OPEN_FLAGS;
} }
svars->opts[F] = svars->drv[F]->prepare_load_box( ctx[F], opts[F] ); svars->opts[F] = svars->drv[F]->prepare_load_box( ctx[F], opts[F] );
@ -1284,10 +1286,30 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
// to expire in the first place. // to expire in the first place.
if (!srec->msg[N]) if (!srec->msg[N])
continue; continue;
nflags = (srec->msg[N]->flags | srec->aflags[N]) & ~srec->dflags[N]; nflags = srec->msg[N]->flags;
if (srec->status & S_DUMMY(N)) {
if (!srec->msg[F])
continue;
// We need to pull in the real Flagged and Seen even if flag
// propagation was not requested, as the placeholder's ones are
// useless (except for un-seeing).
// This results in the somewhat weird situation that messages
// which are not visibly flagged remain unexpired.
sflags = srec->msg[F]->flags;
aflags = (sflags & ~srec->flags) & (F_SEEN | F_FLAGGED);
dflags = (~sflags & srec->flags) & F_SEEN;
nflags = (nflags & (~(F_SEEN | F_FLAGGED) | (srec->flags & F_SEEN)) & ~dflags) | aflags;
}
nflags = (nflags | srec->aflags[N]) & ~srec->dflags[N];
} else {
if (srec->status & S_UPGRADE) {
// The dummy's F & S flags are mostly masked out anyway,
// but we may be pulling in the real ones.
nflags = (srec->pflags | srec->aflags[N]) & ~srec->dflags[N];
} else { } else {
nflags = srec->msg[F]->flags; nflags = srec->msg[F]->flags;
} }
}
if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE | S_EXPIRED))) { if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE | S_EXPIRED))) {
// The message is not deleted, or it is, but only due to being expired. // The message is not deleted, or it is, but only due to being expired.
arecs[alive++] = (alive_srec_t){ srec, nflags }; arecs[alive++] = (alive_srec_t){ srec, nflags };

Loading…
Cancel
Save