From cd2d2df77b5a58043217eed15841c216002b65a2 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Tue, 6 Dec 2016 16:40:40 +0100 Subject: pullimap: replace non RFC 5321-compliant envelope sender addresses by <>. --- Changelog | 8 ++++++++ interimap | 3 ++- pullimap | 23 +++++++++++------------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Changelog b/Changelog index f9ca699..755c8cb 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,11 @@ +interimap (0.4) UNRELEASED + + * pullimap: replace non RFC 5321-compliant envelope sender addresses + (received by the IMAP FETCH ENVELOPE command) by the null sender address + <>. + + -- Guilhem Moulin Tue, 06 Dec 2016 17:37:01 +0100 + interimap (0.3) upstream; + New script 'pullimap', to pull mails from an IMAP mailbox and diff --git a/interimap b/interimap index 7a36c4e..049b564 100755 --- a/interimap +++ b/interimap @@ -577,7 +577,8 @@ sub download_missing($$$@) { my $uid = $mail->{UID}; my $from = first { defined $_ and @$_ } @{$mail->{ENVELOPE}}[2,3,4]; - $from = (defined $from and @$from) ? $from->[0]->[2].'@'.$from->[0]->[3] : ''; + $from = (defined $from and defined $from->[0]->[2] and defined $from->[0]->[3]) + ? $from->[0]->[2].'@'.$from->[0]->[3] : ''; msg(undef, "$source($mailbox): UID $uid from <$from> ($mail->{INTERNALDATE})") unless $CONFIG{quiet}; callback_new_message($idx, $mailbox, $source, $mail, \@uids, $buff, \$bufflen) diff --git a/pullimap b/pullimap index d176464..dca8c49 100755 --- a/pullimap +++ b/pullimap @@ -269,27 +269,26 @@ sub purge() { my $ATTRS = "ENVELOPE INTERNALDATE"; $ATTRS .= " BODY.PEEK[]" unless $CONFIG{'no-delivery'}; -my $RE_ATOM = qr/[A-Za-z0-9\x21\x23-\x27\x2A\x2B\x2D\x2F\x3D\x3F\x5E-\x60\x7B-\x7E]+/; +my $RE_ATOM = qr/[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x41-\x5A\x5E-\x7E]+/; sub pull_callback($$) { my ($uids, $mail) = @_; return unless exists $mail->{RFC822} or $CONFIG{'no-delivery'}; # not for us my $uid = $mail->{UID}; - my $from = first { defined $_ and @$_ } @{$mail->{ENVELOPE}}[2,3,4]; - if (defined $from and @$from) { - my ($l, $d) = @{$from->[0]}[2,3]; - unless ($l =~ /\A$RE_ATOM(?:\.$RE_ATOM)*\z/o) { # quote the local part if not Dot-string (RFC 5321) + my $e = $mail->{ENVELOPE}->[3]; + my $sender = ''; + if (defined $e and defined (my $l = $e->[0]->[2]) and defined (my $d = $e->[0]->[3])) { + if ($l =~ /\A$RE_ATOM(?:\.$RE_ATOM)*\z/o) { + $sender = $l.'@'.$d; + } elsif ($l =~ /\A[\x20-\x7E]*\z/) { + # quote the local part if not Dot-string (RFC 5321) $l =~ s/([\x22\x5C])/\\$1/g; # escape double-quote and backslash - $l = '"' .$l. '"'; + $sender = '"'.$l.'"@'.$d; } - $from = $l .'@'. $d; - $IMAP->fail("Invalid character in MAIL FROM: <$from>") unless $l =~ /\A[\x20-\x7E]*\z/; - } else { - $from = ''; } - $IMAP->log("UID $uid from <$from> ($mail->{INTERNALDATE})") unless $CONFIG{quiet}; + $IMAP->log("UID $uid from <$sender> ($mail->{INTERNALDATE})") unless $CONFIG{quiet}; - sendmail($from, $mail->{RFC822}) unless $CONFIG{'no-delivery'}; + sendmail($sender, $mail->{RFC822}) unless $CONFIG{'no-delivery'}; push @$uids, $uid; writeUID($uid); -- cgit v1.2.3 From 329738ebb74815d8a49feee63efb23d9baa557ee Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Tue, 6 Dec 2016 17:51:04 +0100 Subject: Minor manpage fixes. --- interimap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interimap.md b/interimap.md index b923933..4a321f1 100644 --- a/interimap.md +++ b/interimap.md @@ -37,7 +37,7 @@ message with UID smaller than `UIDNEXT` have been replicated to the other server, and that the metadata (such as flags) of each message with MODSEQ at most `HIGHESTMODSEQ` have been synchronized. Conceptually, the synchronization algorithm is derived from [RFC 4549] -with the [RFC 7162] (section 6) amendments, and works as follows: +with the [RFC 7162] (sec. 6) amendments, and works as follows: 1. `SELECT` (on both servers) a mailbox the current `UIDNEXT` or `HIGHESTMODSEQ` values of which differ from the values found in the database (for @@ -85,7 +85,7 @@ However if some extra argument are provided on the command line, `interimap` ignores said options and synchronizes the given *MAILBOX*es instead. Note that each *MAILBOX* is taken “as is”; in particular, it must be [UTF-7 encoded][RFC 2152], unquoted, and the list -wildcards ‘\*’ and ‘%’ are not interpolated. +wildcards ‘\*’ and ‘%’ are not expanded. If the synchronization was interrupted during a previous run while some messages were being replicated (but before the `UIDNEXT` or -- cgit v1.2.3 From 6fca0d67e7a657452de154e74ad02bf3657db5a1 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 29 May 2017 18:04:19 +0200 Subject: Ensure the lower bound of UID ranges is at least 1. --- Changelog | 1 + lib/Net/IMAP/InterIMAP.pm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 755c8cb..36cbb23 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,7 @@ interimap (0.4) UNRELEASED * pullimap: replace non RFC 5321-compliant envelope sender addresses (received by the IMAP FETCH ENVELOPE command) by the null sender address <>. + - Ensure the lower bound of UID ranges is at least 1. -- Guilhem Moulin Tue, 06 Dec 2016 17:37:01 +0100 diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 7a1ba34..6f148b7 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1185,7 +1185,7 @@ sub pull_new_messages($$&@) { do { my $range = ''; my $first; - my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} // 1; + my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} || 1; foreach my $uid (@ignore) { if ($since < $uid) { $first //= $since; -- cgit v1.2.3 From 783954eaacec35d53674749e302c2ea6ac137935 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sat, 29 Jul 2017 13:36:29 +0200 Subject: Fix manpage generation with pandoc >=1.18. --- Makefile | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index c1513c6..a8474d6 100644 --- a/Makefile +++ b/Makefile @@ -3,22 +3,30 @@ all: pullimap.1 interimap.1 # upper case the headers and remove the links %.1: %.md @pandoc -S -f markdown -t json "$<" | \ - jq ".[1][] |= if .t == \"Header\" then .c[2][] |= (if .t == \"Str\" then .c |= ascii_upcase else . end) else . end" | \ - jq " \ - def fixit: \ - if type == \"object\" then \ - if .t == \"Link\" then \ - if .c[2][0][0:7] == \"mailto:\" then . else .c[1][] end \ - else \ - map_values(fixit) \ - end \ - else if type == \"array\" then \ - map(fixit) \ - else \ - . \ - end \ - end; \ - map(fixit)" | \ + jq " \ + def fixheaders: \ + if .t == \"Header\" then \ + .c[2][] |= (if .t == \"Str\" then .c |= ascii_upcase else . end)\ + else \ + . \ + end; \ + def fixlinks: \ + if type == \"object\" then \ + if .t == \"Link\" then \ + if .c[2][0][0:7] == \"mailto:\" then . else .c[1][] end \ + else \ + map_values(fixlinks) \ + end \ + else if type == \"array\" then \ + map(fixlinks) \ + else \ + . \ + end \ + end; \ + { \"pandoc-api-version\" \ + , meta \ + , blocks: .blocks | map(fixheaders) | map(fixlinks) \ + }" | \ pandoc -sS -f json -t man -o "$@" install: -- cgit v1.2.3