diff options
| author | Guilhem Moulin <guilhem@fripost.org> | 2015-07-26 15:53:13 +0200 | 
|---|---|---|
| committer | Guilhem Moulin <guilhem@fripost.org> | 2015-07-26 15:54:43 +0200 | 
| commit | 464862335d1bc09437d4238214d30a1db7b829bd (patch) | |
| tree | 191bebd200c0a14581ab08bc921a7568da9c634d /imapsync | |
| parent | 0ceb23a6c85c1c77dfac5e8eac6bf66657d08d07 (diff) | |
bugfix: Fetching new messages from local and adding them to remote modifies its UIDNEXT.
So we need to check again the first $source (remote) whenever the last
one (local) added new messages to it.
Diffstat (limited to 'imapsync')
| -rwxr-xr-x | imapsync | 46 | 
1 files changed, 26 insertions, 20 deletions
| @@ -961,26 +961,32 @@ sub callback_new_message_flush($$$@) {  # the given UIDs.  sub sync_messages($$;$$) {      my ($idx, $mailbox, $lIgnore, $rIgnore) = @_; -    my ($buff, $bufflen, @lUIDs); - -    # get new messages from remote (except @$rIgnore) and APPEND them to local -    ($buff, $bufflen) = ([], 0); -    undef $buff if $lIMAP->incapable('MULTIAPPEND'); -    $rIMAP->pull_new_messages(sub($) { -        callback_new_message($idx, $mailbox, 'remote', shift, \@lUIDs, $buff, \$bufflen) -    }, @{$rIgnore // []}); -    push @lUIDs, callback_new_message_flush($idx, $mailbox, 'remote', @$buff) -        if defined $buff and @$buff; - -    # get new messages from local (except @$lIgnore and the newly allocated local -    # UIDs @lUIDs) and APPEND them to remote -    ($buff, $bufflen) = ([], 0); -    undef $buff if $rIMAP->incapable('MULTIAPPEND'); -    $lIMAP->pull_new_messages(sub($) { -        callback_new_message($idx, $mailbox, 'local', shift, undef, $buff, \$bufflen) -    }, @{$lIgnore // []}, @lUIDs); -    callback_new_message_flush($idx, $mailbox, 'local', @$buff) -        if defined $buff and @$buff; + +    my %ignore = (local => ($lIgnore // []), remote => ($rIgnore // [])); +    my $loop; +    do { +        # get new messages from $source (except @{$ignore{$source}}) and APPEND them to $target +        foreach my $source (qw/remote local/) { # pull remote mails first +            my $target = $source eq 'remote' ? 'local' : 'remote'; +            my $buff    = [] unless ($target eq 'local' ? $lIMAP : $rIMAP)->incapable('MULTIAPPEND'); +            my $bufflen = 0; +            my @tUIDs; + +            ($source eq 'remote' ? $rIMAP : $lIMAP)->pull_new_messages(sub($) { +                callback_new_message($idx, $mailbox, $source, shift, \@tUIDs, $buff, \$bufflen) +            }, @{$ignore{$source}}); + +            push @tUIDs, callback_new_message_flush($idx, $mailbox, $source, @$buff) +                if defined $buff and @$buff; +            push @{$ignore{$target}}, @tUIDs; + +            $loop = @tUIDs ? 1 : 0; +        } +        # since $source modifies $target's UIDNEXT upon new mails, we +        # need to check again the first $source (remote) whenever the +        # last one (local) added new messages to it +    } +    while ($loop);      # both local and remote UIDNEXT are now up to date; proceed with      # pending flag updates and vanished messages | 
