aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2016-03-08 23:13:43 +0100
committerGuilhem Moulin <guilhem@fripost.org>2016-03-08 23:13:43 +0100
commitec87e1965d758bc3af4403a3cf469c3297f8cb1a (patch)
tree64989e2ace4e84da226177cdc9a8e95bd5c2f5ef
parentaecdd0c6657e3edb0482751efffdcafb96f2c2c5 (diff)
parent6bf9ee9a1e1c704490489f682dfe106f2c1ee46a (diff)
Merge branch 'master' into debian
-rw-r--r--README14
-rw-r--r--interimap.18
-rw-r--r--lib/Net/IMAP/InterIMAP.pm13
-rwxr-xr-xpullimap15
-rw-r--r--pullimap.110
-rw-r--r--pullimap@.service12
6 files changed, 46 insertions, 26 deletions
diff --git a/README b/README
index 2b577a5..8fcbb05 100644
--- a/README
+++ b/README
@@ -1,9 +1,11 @@
InterIMAP is a fast bidirectional synchronization program for QRESYNC-capable
-IMAP4rev1 servers. Consult the manual for more information.
+IMAP4rev1 servers. PullIMAP retrieves messages a remote IMAP mailbox and
+deliver them to a SMTP session. Consult the manuals for more information.
+ https://guilhem.org/man/interimap.1.html
+ https://guilhem.org/man/pullimap.1.html
-#######################################################################
-
+_______________________________________________________________________
Compared to IMAP-to-Maildir synchronization solutions like OfflineIMAP,
adding an IMAP server between the Maildir storage and the MUA saves
@@ -32,8 +34,7 @@ extensions are:
* UNSELECT [RFC3691].
-#######################################################################
-
+_______________________________________________________________________
IMAP traffic is mostly text (beside message bodies perhaps) hence
compresses pretty well: enabling compression can save a great amount of
@@ -81,8 +82,7 @@ compress=DEFLATE to the configuration can also greatly reduce bandwidth
usage with regular INET sockets (type=imaps or type=imap).
-#######################################################################
-
+_______________________________________________________________________
InterIMAP is Copyright© 2015 Guilhem Moulin ⟨guilhem@fripost.org⟩, and
licensed for use under the GNU General Public License version 3 or
diff --git a/interimap.1 b/interimap.1
index e23b953..93e463e 100644
--- a/interimap.1
+++ b/interimap.1
@@ -33,7 +33,7 @@ Conceptually, the synchronization algorithm is derived from [RFC4549]
with the [RFC7162, section 6] amendments, and works as follows:
.nr step 1 1
-.IP \n[step]. 8
+.IP \n[step]. 4
SELECT (on both servers) a mailbox the current UIDNEXT or HIGHESTMODSEQ
values of which differ from the values found in the database (for either
server). Use the QRESYNC SELECT parameter from [RFC7162] to list
@@ -298,7 +298,7 @@ advertising it.
the \(lq[remote]\(rq section.)
.TP
-.I null-stderr
+.I null\-stderr
Whether to redirect \fIcommand\fR's standard error to \(lq/dev/null\(rq
for type \fItype\fR=tunnel.
(Default: \(lqNO\(rq.)
@@ -353,7 +353,7 @@ authentication if \(lq\fISSL_verify\fR=YES\(rq.
Performance is better for servers supporting the following extensions to
the IMAP4rev1 [RFC3501] protocol:
-.IP \[bu]
+.IP \[bu] 4
LITERAL+ [RFC2088] non-synchronizing literals (recommended),
.IP \[bu]
MULTIAPPEND [RFC3502] (recommended),
@@ -366,7 +366,7 @@ UNSELECT [RFC3691].
.SH KNOWN BUGS AND LIMITATIONS
-.IP \[bu]
+.IP \[bu] 4
Using \fBInterIMAP\fR on two identical servers with a non-existent or
empty database will duplicate each message due to the absence of
local/remote UID association.
diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm
index be62a9d..785de38 100644
--- a/lib/Net/IMAP/InterIMAP.pm
+++ b/lib/Net/IMAP/InterIMAP.pm
@@ -1366,15 +1366,18 @@ sub _tcp_connect($$$) {
my ($err, @res) = getaddrinfo($host, $port, \%hints);
$self->fail("Can't getaddrinfo: $err") if $err ne '';
+ SOCKETS:
foreach my $ai (@res) {
- socket my $s, $ai->{family}, $ai->{socktype}, $ai->{protocol};
+ socket (my $s, $ai->{family}, $ai->{socktype}, $ai->{protocol}) or $self->panic("connect: $!");
# TODO: add a connection timeout
# http://devpit.org/wiki/Connect%28%29_with_timeout_%28in_Perl%29
- if (defined $s and connect($s, $ai->{addr})) {
- my $flags = fcntl($s, F_GETFL, 0) or $self->panic("fcntl F_GETFL: $!");
- fcntl($s, F_SETFL, $flags | FD_CLOEXEC) or $self->panic("fcntl F_SETFL: $!");
- return $s;
+ until (connect($s, $ai->{addr})) {
+ next if $! == EINTR; # try again if connect(2) was interrupted by a signal
+ next SOCKETS;
}
+ my $flags = fcntl($s, F_GETFL, 0) or $self->panic("fcntl F_GETFL: $!");
+ fcntl($s, F_SETFL, $flags | FD_CLOEXEC) or $self->panic("fcntl F_SETFL: $!");
+ return $s;
}
$self->fail("Can't connect to $host:$port");
}
diff --git a/pullimap b/pullimap
index 0e31a90..c16d6ac 100755
--- a/pullimap
+++ b/pullimap
@@ -221,7 +221,7 @@ sub smtp_send(@) {
$CONF->{'logger-fd'} = \*STDERR if $CONFIG{debug};
my $IMAP = do {
my %config = (%$CONF, %CONFIG{qw/quiet debug/}, name => $ARGV[0]);
- $config{keepalive} = 1 if defined $CONFIG{idle} and $config{type} ne 'tunnel';
+ $config{keepalive} = 1 if defined $CONFIG{idle};
Net::IMAP::InterIMAP::->new( %config );
};
@@ -234,11 +234,11 @@ sub purge() {
return unless 1<$uidnext;
my $set = "1:".($uidnext-1);
- my $now = time;
- return if defined $LAST_PURGED and $now - $LAST_PURGED < 6*3600;
- $LAST_PURGED = $now;
-
unless ($days == 0) {
+ my $now = time;
+ return if defined $LAST_PURGED and $now - $LAST_PURGED < 6*3600; # purge every 6h
+ $LAST_PURGED = $now;
+
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);
@@ -254,7 +254,8 @@ sub purge() {
# Use BODY.PEEK[] so if something gets wrong, unpulled messages
# won't be marked as \Seen in the mailbox
-my $ATTRS = "ENVELOPE INTERNALDATE BODY.PEEK[]";
+my $ATTRS = "ENVELOPE INTERNALDATE";
+$ATTRS .= " BODY.PEEK[]" unless $CONFIG{'no-delivery'};
# Pull new messages from IMAP and deliver them to SMTP, then update the
# statefile
@@ -265,7 +266,7 @@ sub pull(;$) {
# invariant: we're at pos 8 + 4*(1+$#ignore + 1+$#uids) in the statefile
$IMAP->pull_new_messages($ATTRS, sub($) {
my $mail = shift;
- return unless exists $mail->{RFC822}; # not for us
+ 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];
diff --git a/pullimap.1 b/pullimap.1
index 52a6152..57a4adf 100644
--- a/pullimap.1
+++ b/pullimap.1
@@ -12,8 +12,7 @@ PullIMAP \- Pull mails from an IMAP mailbox and deliver them to a SMTP session
.PP
.B PullIMAP\fR retrieves messages from an IMAP mailbox and deliver them
to a SMTP or LMTP transmission channel.
-It can also remove delivered messages after a configurable retention
-period.
+It can also remove old messages after a configurable retention period.
.PP
A statefile is used to keep track of the mailbox's UIDVALIDITY and
@@ -33,6 +32,7 @@ environment variable is unset.
Don't exit after a successful poll; instead, keep the connection open
and issue IDLE commands (requires an IMAP server supporting RFC 2177) to
watch for updates in the mailbox.
+This also sets SO_KEEPALIVE on the socket.
Each IDLE is terminated after at most \fIseconds\fR (29 minutes by
default) to avoid being logged out for inactivity.
@@ -113,6 +113,10 @@ Message recipient.
Retention period (in days), after which messages are removed from the
IMAP server. (The value is at best 24h accurate due to IMAP SEARCH
criterion ignoring time and timezone.)
+If \fIpurge\-after\fR is set to \(lq0\(rq then messages are deleted
+immediately after delivery. Otherwise \fBPullIMAP\fR issues an IMAP
+SEARCH command to list old messages; if \fB\-\-idle\fR is set then the
+SEARCH command is issued again every 6 hours.
.TP
.I type
@@ -180,7 +184,7 @@ advertising it.
(Default: \(lqYES\(rq.)
.TP
-.I null-stderr
+.I null\-stderr
Whether to redirect \fIcommand\fR's standard error to \(lq/dev/null\(rq
for type \fItype\fR=tunnel.
(Default: \(lqNO\(rq.)
diff --git a/pullimap@.service b/pullimap@.service
new file mode 100644
index 0000000..d066886
--- /dev/null
+++ b/pullimap@.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Pull mails from an IMAP mailbox and deliver them to a SMTP session
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+ExecStart=/usr/bin/pullimap --idle %i
+RestartSec=2min
+Restart=always
+
+[Install]
+WantedBy=default.target