aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2018-05-09 01:11:55 +0200
committerGuilhem Moulin <guilhem@fripost.org>2018-05-09 01:11:55 +0200
commitc41c280d3a1243ae445311e1ededd1dedc1484c3 (patch)
treef4ed7297fc7922dfa13a484e2154531b0e4ca0c5
parenta95890cc5c18a2c4a16d6929b2725c6ba3fc3e5e (diff)
Add support for untagged ESEARCH responses from RFC 4731.
-rw-r--r--Changelog1
-rw-r--r--lib/Net/IMAP/InterIMAP.pm24
2 files changed, 21 insertions, 4 deletions
diff --git a/Changelog b/Changelog
index 74b36fb..f2fee83 100644
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,7 @@ interimap (0.4) UNRELEASED
(received by the IMAP FETCH ENVELOPE command) by the null sender address
<>.
+ Library: new API idle_start() and idle_stop().
+ + Add support for untagged ESEARCH responses from RFC 4731.
- Ensure the lower bound of UID ranges is at least 1.
- Fix manpage generation with pandoc >=2.1.
diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm
index 9719de2..4a9ffd9 100644
--- a/lib/Net/IMAP/InterIMAP.pm
+++ b/lib/Net/IMAP/InterIMAP.pm
@@ -594,12 +594,15 @@ sub incapable($@) {
# $self->search($criterion)
-# Issue an UID SEARCH command with the given $criterion. Return the
-# list of matching UIDs.
+# Issue an UID SEARCH command with the given $criterion. For the "normal"
+# UID SEARCH command from RFC 3501, return the list of matching UIDs;
+# for the extended UID SEARCH command from RFC 4731 (ensuring ESEARCH
+# capability is the caller's responsibility), return an "UID"
+# indicator followed by a hash containing search data pairs.
sub search($$) {
my ($self, $crit) = @_;
my @res;
- $self->_send('UID SEARCH '.$crit, sub(@) {push @res, @_});
+ $self->_send('UID SEARCH '.$crit, sub(@) {@res = @_});
return @res
}
@@ -1942,7 +1945,9 @@ sub _send($$;&) {
$self->_recv($tag, undef, $cmd);
}
else {
- my $set = $$command =~ /\AUID (?:FETCH|STORE) ([0-9:,*]+)/ ? $1 : undef;
+ my $set = $$command =~ /\AUID (?:FETCH|STORE) ([0-9:,*]+)/ ? $1
+ : $$command =~ /\AUID SEARCH / ? "\"$tag\"" # RFC 4466's tag-string
+ : undef;
$self->_recv($tag, $callback, $cmd, $set);
}
}
@@ -2283,6 +2288,17 @@ sub _resp($$;&$$) {
elsif (/\ASEARCH((?: [0-9]+)*)\z/) {
$callback->(split(/ /, ($1 =~ s/^ //r))) if defined $callback and $cmd eq 'SEARCH';
}
+ elsif (s/\AESEARCH \(TAG \Q$set\E\)( UID)?//) {
+ my $uid = $1;
+ my %ret; # RFC 4731
+ while ($_ ne '') {
+ $self->fail("RFC 4731 violation in ESEARCH response")
+ # XXX RFC 4466's tagged-ext-comp unsupported
+ unless s/\A ($RE_ATOM_CHAR+) ([0-9,:]+)//;
+ $ret{uc $1} = $2;
+ }
+ $callback->($uid, %ret) if defined $callback and $cmd eq 'SEARCH';
+ }
elsif (s/\ALIST \((\\?$RE_ATOM_CHAR+(?: \\?$RE_ATOM_CHAR+)*)?\) ("(?:\\[\x22\x5C]|[\x01-\x09\x0B\x0C\x0E-\x21\x23-\x5B\x5D-\x7F])"|NIL) //) {
my ($delim, $attrs) = ($2, $1);
my @attrs = defined $attrs ? split(/ /, $attrs) : ();