aboutsummaryrefslogtreecommitdiffstats
path: root/interimap
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-09-09 16:05:36 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-09-09 22:05:43 +0200
commit1abb196660516f85b2ec13673aa28e6cf8a24b41 (patch)
treeeba2ac643901362f0272baa65d467d24bda9df26 /interimap
parent9fb0576765624cc27a1c06aebc9f4ef5df31ba30 (diff)
Add support for the Binary Content extension [RFC3516].
Unfortunately as of Debian Wheezy it doesn't work for Dovecot with COMPRESS=DEFLATE [RFC4978] and non-synchronizing literals. perl -e 'use Compress::Raw::Zlib; print "a COMPRESS DEFLATE\r\n"; sleep 1; my $d = new Compress::Raw::Zlib::Deflate( -WindowBits => -15 ); $d->deflate("b APPEND TRASH ~{1+}\r\nx\r\n", my $buf); print $buf; $d->flush($buf, Z_SYNC_FLUSH); print $buf; sleep 1; ' | /usr/lib/dovecot/imap imap(guilhem): Panic: stream doesn't support seeking backwards Interestingly, it works just fine for non-binary literals: perl -e 'use Compress::Raw::Zlib; print "a COMPRESS DEFLATE\r\n"; sleep 1; my $d = new Compress::Raw::Zlib::Deflate( -WindowBits => -15 ); $d->deflate("b APPEND TRASH {1+}\r\nx\r\n", my $buf); print $buf; $d->flush($buf, Z_SYNC_FLUSH); print $buf; sleep 1; ' | /usr/lib/dovecot/imap However I can't reproduce the problem Dovecot 2.2.18 and Debian Sid (but it doesn't help to install Dovecot from testing to my Wheezy box.)
Diffstat (limited to 'interimap')
-rwxr-xr-xinterimap16
1 files changed, 11 insertions, 5 deletions
diff --git a/interimap b/interimap
index af2c510..81582f2 100755
--- a/interimap
+++ b/interimap
@@ -74,6 +74,7 @@ my $CONF = read_config( delete $CONFIG{config} // $NAME
, 'list-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/
, 'list-select-opts' => qr/\A([\x21\x23\x24\x26\x27\x2B-\x5B\x5E-\x7A\x7C-\x7E]+)\z/
, 'ignore-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/
+ , 'use-binary' => qr/\A(YES|NO)\z/i,
);
my ($DBFILE, $LOCKFILE, $LOGGER_FD);
@@ -511,6 +512,10 @@ sub sync_mailbox_list() {
sync_mailbox_list();
($lIMAP, $rIMAP) = map {$IMAP->{$_}->{client}} qw/local remote/;
+my $ATTRS = 'MODSEQ FLAGS INTERNALDATE '.
+ (((!defined $CONF->{_} or uc ($CONF->{_}->{'use-binary'} // 'YES') eq 'YES') and
+ !$lIMAP->incapable('BINARY') and !$rIMAP->incapable('BINARY'))
+ ? 'BINARY' : 'BODY').'.PEEK[]';
#############################################################################
@@ -592,10 +597,10 @@ sub download_missing($$$@) {
my ($buff, $bufflen) = ([], 0);
undef $buff if ($target eq 'local' ? $lIMAP : $rIMAP)->incapable('MULTIAPPEND');
- my $attrs = join ' ', qw/MODSEQ FLAGS INTERNALDATE ENVELOPE BODY.PEEK[]/;
+ my $attrs = $ATTRS.' ENVELOPE';
($source eq 'local' ? $lIMAP : $rIMAP)->fetch(compact_set(@set), "($attrs)", sub($) {
my $mail = shift;
- return unless exists $mail->{RFC822}; # not for us
+ return unless exists $mail->{RFC822} or exists $mail->{BINARY}; # not for us
my $uid = $mail->{UID};
my $from = first { defined $_ and @$_ } @{$mail->{ENVELOPE}}[2,3,4];
@@ -964,9 +969,10 @@ sub sync_known_messages($$) {
# after the FETCH.
sub callback_new_message($$$$;$$$) {
my ($idx, $mailbox, $name, $mail, $UIDs, $buff, $bufflen) = @_;
- return unless exists $mail->{RFC822}; # not for us
- my $length = length $mail->{RFC822};
+ my $length = defined $mail->{RFC822} ? length($mail->{RFC822})
+ : defined $mail->{BINARY} ? length($mail->{BINARY})
+ : return; # not for us
if ($length == 0) {
msg("$name($mailbox)", "WARNING: Ignoring new 0-length message (UID $mail->{UID})");
return;
@@ -1030,7 +1036,7 @@ sub sync_messages($$;$$) {
my $bufflen = 0;
my @tUIDs;
- ($source eq 'remote' ? $rIMAP : $lIMAP)->pull_new_messages(sub($) {
+ ($source eq 'remote' ? $rIMAP : $lIMAP)->pull_new_messages($ATTRS, sub($) {
callback_new_message($idx, $mailbox, $source, shift, \@tUIDs, $buff, \$bufflen)
}, @{$ignore{$source}});