aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog9
-rw-r--r--Makefile40
-rwxr-xr-xinterimap3
-rw-r--r--interimap.md4
-rw-r--r--lib/Net/IMAP/InterIMAP.pm2
-rwxr-xr-xpullimap23
6 files changed, 49 insertions, 32 deletions
diff --git a/Changelog b/Changelog
index f9ca699..36cbb23 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,12 @@
+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 <guilhem@guilhem.org> 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/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:
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/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
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;
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);