isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit fe4e478e95a3474241a5d7fea594302a3a5a52df
parent 1ca278ad0d11166b3ffbe116c5c90f6cda09ccb5
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Fri,  7 Jan 2022 18:25:16 +0100

fix expiration completion after external expunge

when the expiration is interrupted, but an external expunge removes the
near-side message before we resume, we would just drop the transaction,
resulting in an "unmarked" orphan.

a corner case is an expiration that finishes, but initially isn't
expunged (probably due to an interruption), followed by an unexpiration
that gets interrupted, and the message being expunged externally
(because it's still marked as deleted). we obviously can't complete
that transaction without re-propagating the message, so effectively
cancel it instead.

Diffstat:
Msrc/sync.c | 5+++++
1 file changed, 5 insertions(+), 0 deletions(-)

diff --git a/src/sync.c b/src/sync.c @@ -1047,6 +1047,11 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux // The target may be in an unknown state (not fetched). if ((t == F) && (srec->status & (S_EXPIRE|S_EXPIRED))) { /* Don't propagate deletion resulting from expiration. */ + if (~srec->status & (S_EXPIRE | S_EXPIRED)) { + // An expiration was interrupted, but the message was expunged since. + srec->status |= S_EXPIRE | S_EXPIRED; // Override failed unexpiration attempts. + JLOG( "~ %u %u %u", (srec->uid[F], srec->uid[N], srec->status), "forced expiration commit" ); + } JLOG( "> %u %u 0", (srec->uid[F], srec->uid[N]), "near side expired, orphaning far side" ); srec->uid[N] = 0; } else {