aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-07-24 17:29:52 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-07-24 17:35:29 +0200
commit7da4bafd83dbd8c84cc529b132ece06497d6f49d (patch)
tree46285efa0830d9a4983d847ff1c140fd7273e121
parent59686220211905705b04e571008c6dedecf6243f (diff)
bugfix: new messages can be received while FETCHing new messages.
-rw-r--r--lib/Net/IMAP/Sync.pm69
1 files changed, 38 insertions, 31 deletions
diff --git a/lib/Net/IMAP/Sync.pm b/lib/Net/IMAP/Sync.pm
index 1aceb70..fc1ab81 100644
--- a/lib/Net/IMAP/Sync.pm
+++ b/lib/Net/IMAP/Sync.pm
@@ -651,12 +651,12 @@ sub append($$$@) {
my @uids;
foreach (split /,/, $uidset) {
if (/\A([0-9]+)\z/) {
- $UIDNEXT = $1 + 1 if $UIDNEXT < $1;
+ $UIDNEXT = $1 + 1 if $UIDNEXT <= $1;
push @uids, $1;
} elsif (/\A([0-9]+):([0-9]+)\z/) {
my ($min, $max) = $1 <= $2 ? ($1,$2) : ($2,$1);
push @uids, ($min .. $max);
- $UIDNEXT = $max + 1 if $UIDNEXT < $max;
+ $UIDNEXT = $max + 1 if $UIDNEXT <= $max;
} else {
$self->panic($_);
}
@@ -917,36 +917,43 @@ sub pull_new_messages($$@) {
my $attrs = join ' ', qw/MODSEQ FLAGS INTERNALDATE/, @attrs, 'BODY.PEEK[]';
my $mailbox = $self->{_SELECTED} // $self->panic();
- my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} // 1;
-
- my $range = '';
- my $first;
- foreach my $uid (@ignore) {
- if ($since < $uid) {
- $first //= $since;
- $range .= ',' if $range ne '';
- $range .= $since;
- $range .= ':'.($uid-1) if $since < $uid-1;
- $since = $uid+1;
- }
- elsif ($since == $uid) {
- $since++;
- }
- }
-
- $first //= $since;
- $range .= ',' if $range ne '';
- # 2^32-1: don't use '*' since the highest UID can be known already
- $range .= "$since:4294967295";
-
- my $UIDNEXT = $self->{_CACHE}->{$mailbox}->{UIDNEXT};
- $self->panic() unless defined $UIDNEXT and $UIDNEXT > 0; # sanity check
- $self->_send("UID FETCH $range ($attrs)", $callback) if $first < $UIDNEXT;;
+ my $UIDNEXT;
+ do {
+ my $range = '';
+ my $first;
+ my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} // 1;
+ foreach my $uid (@ignore) {
+ if ($since < $uid) {
+ $first //= $since;
+ $range .= ',' if $range ne '';
+ $range .= $since;
+ $range .= ':'.($uid-1) if $since < $uid-1;
+ $since = $uid+1;
+ }
+ elsif ($since == $uid) {
+ $since++;
+ }
+ }
- # update the persistent cache for UIDNEXT (not for HIGHESTMODSEQ
- # since there might be pending updates)
- $self->set_cache($mailbox, %{$self->{_CACHE}->{$mailbox}}{UIDNEXT});
+ $first //= $since;
+ $range .= ',' if $range ne '';
+ # 2^32-1: don't use '*' since the highest UID can be known already
+ $range .= "$since:4294967295";
+
+ $UIDNEXT = $self->{_CACHE}->{$mailbox}->{UIDNEXT} // $self->panic(); # sanity check
+ $self->_send("UID FETCH $range ($attrs)", sub(%) {
+ my %mail = @_;
+ $UIDNEXT = $mail{UID} + 1 if $UIDNEXT <= $mail{UID};
+ $callback->(%mail) if defined $callback;
+ }) if $first < $UIDNEXT;
+
+ # update the persistent cache for UIDNEXT (not for HIGHESTMODSEQ
+ # since there might be pending updates)
+ $self->set_cache($mailbox, UIDNEXT => $UIDNEXT);
+ }
+ # loop if new messages were received in the meantime
+ while ($UIDNEXT < $self->{_CACHE}->{$mailbox}->{UIDNEXT});
}
@@ -1461,7 +1468,7 @@ sub _resp($$;$$$) {
# always present, cf RFC 3501 section 6.4.8
$mail{UID} = $1;
# the actual UIDNEXT is *at least* that
- $cache->{UIDNEXT} = $1+1 if !defined $cache->{UIDNEXT} or $cache->{UIDNEXT} < $1;
+ $cache->{UIDNEXT} = $1+1 if !defined $cache->{UIDNEXT} or $cache->{UIDNEXT} <= $1;
}
if (s/\AMODSEQ \(([0-9]+)\)//) { # RFC 4551/7162 CONDSTORE/QRESYNC
# always present in unsolicited FETCH responses if QRESYNC has been enabled