diff options
| -rwxr-xr-x | interimap | 4 | ||||
| -rw-r--r-- | lib/Net/IMAP/InterIMAP.pm | 17 | ||||
| -rwxr-xr-x | pullimap | 10 | 
3 files changed, 25 insertions, 6 deletions
@@ -2,7 +2,7 @@  #----------------------------------------------------------------------  # Fast bidirectional synchronization for QRESYNC-capable IMAP servers -# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# Copyright © 2015,2016 Guilhem Moulin <guilhem@fripost.org>  #  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU General Public License as published by @@ -65,12 +65,12 @@ usage(1) if defined $COMMAND and defined $CONFIG{watch};  usage(1) if $CONFIG{target} and !(defined $COMMAND and ($COMMAND eq 'delete'or $COMMAND eq 'rename'));  $CONFIG{watch} = 60 if defined $CONFIG{watch} and $CONFIG{watch} == 0;  @ARGV = map {uc $_ eq 'INBOX' ? 'INBOX' : $_ } @ARGV; # INBOX is case-insensitive +die "Invalid mailbox name $_" foreach grep !/\A([\x01-\x7F]+)\z/, @ARGV;  my $CONF = read_config( delete $CONFIG{config} // $NAME                        , [qw/_ local remote/]                        , database => qr/\A(\P{Control}+)\z/ -                      , logfile => qr/\A(\/\P{Control}+)\z/                        , '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/ diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 7d6e468..15682b3 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -58,6 +58,7 @@ my %OPTIONS = (      command => qr/\A(\P{Control}+)\z/,      'null-stderr' => qr/\A(YES|NO)\z/i,      compress => qr/\A($RE_ATOM_CHAR+(?: $RE_ATOM_CHAR+)*)\z/, +    logfile => qr/\A(\/\P{Control}+)\z/,      SSL_protocols => qr/\A(!?$RE_SSL_PROTO(?: !?$RE_SSL_PROTO)*)\z/,      SSL_fingerprint => qr/\A((?:[A-Za-z0-9]+\$)?\p{AHex}+)\z/,      SSL_cipherlist => qr/\A(\P{Control}+)\z/, @@ -535,9 +536,10 @@ sub logger($@) {      if (defined $self->{'logger-fd'}->fileno and defined $self->{'logger-fd'}->fileno              and $self->{'logger-fd'}->fileno != fileno STDERR) {          my ($s, $us) = Time::HiRes::gettimeofday(); -        $prefix = POSIX::strftime("%b %e %H:%M:%S", localtime($s)).".$us "; +        $prefix = POSIX::strftime("%b %e %H:%M:%S", localtime($s)).".$us"; +        $prefix .= ' ' if defined $self->{name} or $self->{_STATE} eq 'SELECTED';      } -    $prefix .= $self->{name} // ''; +    $prefix .= $self->{name} if defined $self->{name};      $prefix .= "($self->{_SELECTED})" if $self->{_STATE} eq 'SELECTED';      $prefix .= ': ' unless $prefix eq '';      $self->{'logger-fd'}->say($prefix, @_); @@ -1255,6 +1257,17 @@ sub push_flag_updates($$@) {  } +# $self->silent_store($set, $mod, @flags) +#   Set / Add / Update the flags list on the UID $set. +#   /!\ there is no check that messages flags been set! +sub silent_store($$$@) { +    my $self = shift; +    my $set = shift; +    my $mod = shift; +    $self->_send("UID STORE $set ${mod}FLAGS.SILENT (".join(' ', @_).")"); +} + +  #############################################################################  # Private methods @@ -29,7 +29,7 @@ use Getopt::Long qw/:config posix_default no_ignore_case gnu_getopt auto_version  use List::Util 'first';  use lib 'lib'; -use Net::IMAP::InterIMAP 'read_config'; +use Net::IMAP::InterIMAP qw/read_config compact_set/;  my %CONFIG;  sub usage(;$) { @@ -140,11 +140,16 @@ do {          writeUID(1);      }      else { +        # put the remaining UIDs in the @ignore list: these messages +        # have already been delivered, but the process exited before the +        # statefile was updated          while (defined (my $uid = readUID())) {              push @ignore, $uid;          }      } +    # use BODY.PEEK[] so if something gets wrong, unpulled messages +    # won't be marked as \Seen in the mailbox      my $attrs = join ' ', qw/ENVELOPE INTERNALDATE BODY.PEEK[]/;      my @uid; @@ -163,7 +168,8 @@ do {          writeUID($uid);      }, @ignore); -    # TODO mark (@ignore, @uid) as seen +    # now that everything has been deliverd, mark @ignore and @uid as \Seen +    $IMAP->silent_store(compact_set(@ignore, @uid), '+', '\Seen') if @ignore or @uid;      # update the statefile      sysseek($STATE, 4, SEEK_SET) // die "Can't seek: $!";  | 
