From 15cd4f6ea5074ffb33de8670bd1877603e504289 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 10 May 2018 17:56:45 +0200 Subject: pullimap: use extended SEARCH (RFC 4731) when available --- Changelog | 2 ++ pullimap | 18 ++++++++++++++---- pullimap.md | 11 ++++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Changelog b/Changelog index bb355e0..7939fa2 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,8 @@ interimap (0.4) UNRELEASED <>. + Library: new API idle_start() and idle_stop(). + Add support for untagged ESEARCH responses from RFC 4731. + + pullimap: Use extended SEARCH commands (RFC 4731) if supported by + the server to search old mail and EXPUNGE them. - Ensure the lower bound of UID ranges is at least 1. - Fix manpage generation with pandoc >=2.1. diff --git a/pullimap b/pullimap index dca8c49..736bbff 100755 --- a/pullimap +++ b/pullimap @@ -249,10 +249,20 @@ sub purge() { my @now = gmtime($now - $days*86400); my @m = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; # RFC 3501's date-month my $date = sprintf("%02d-%s-%04d", $now[3], $m[$now[4]], $now[5]+1900); - my @uid = $IMAP->search("UID $set BEFORE $date"); - - $set = @uid ? compact_set(@uid) : undef; - $IMAP->log("Removing ".($#uid+1)." UID(s) $set") if defined $set and !$CONFIG{quiet}; + my $ext = $IMAP->incapable('ESEARCH') ? undef : [qw/COUNT ALL/]; + my @uid = $IMAP->search((defined $ext ? "RETURN (".join(' ', @$ext).') ' : '') + ."UID $set BEFORE $date"); + my $count; + if (defined $ext) { + my ($uid_indicator, %resp) = @uid; + $IMAP->panic() unless defined $uid_indicator and $uid_indicator = 'UID'; + $count = $resp{COUNT} // $IMAP->panic(); + $set = $resp{ALL}; # MUST NOT be present if there are no matches + } else { + $count = $#uid+1; + $set = $count == 0 ? undef : compact_set(@uid); + } + $IMAP->log("Removing $count UID(s) $set") if $count > 0 and !$CONFIG{quiet}; } if (defined $set) { diff --git a/pullimap.md b/pullimap.md index cb2a07a..3e8aae3 100644 --- a/pullimap.md +++ b/pullimap.md @@ -121,9 +121,10 @@ Valid options are: the IMAP server. (The value is at best 24h accurate due to the IMAP `SEARCH` criterion ignoring time and timezone.) If *purge-after* is set to `0` then messages are deleted immediately - after delivery. Otherwise `pullimap` issues an IMAP `SEARCH` - command to list old messages; if `--idle` is set then the `SEARCH` - command is issued again every 12 hours. + after delivery. Otherwise `pullimap` issues an IMAP `SEARCH` (or + extended `SEARCH` on server advertizing the [`ESEARCH`][RFC 4731] + capability) command to list old messages; if `--idle` is set then + the `SEARCH` command is issued again every 12 hours. *type* @@ -339,6 +340,9 @@ Standards [RFC 4315], December 2005. * A. Gulbrandsen, _The IMAP `COMPRESS` Extension_, [RFC 4978], August 2007. + * A. Melnikov and D. Cridland, _IMAP4 Extension to SEARCH Command for + Controlling What Kind of Information Is Returned_, + [RFC 4731], November 2006. * R. Siemborski and A. Gulbrandsen, _IMAP Extension for Simple Authentication and Security Layer (SASL) Initial Client Response_, [RFC 4959], September 2007. @@ -358,6 +362,7 @@ Standards [RFC 4978]: https://tools.ietf.org/html/rfc4978 [RFC 1928]: https://tools.ietf.org/html/rfc1928 [RFC 1929]: https://tools.ietf.org/html/rfc1929 +[RFC 4731]: https://tools.ietf.org/html/rfc4731 [INI file]: https://en.wikipedia.org/wiki/INI_file [`fetchmail`(1)]: http://www.fetchmail.info/ -- cgit v1.2.3