aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile29
-rw-r--r--pullimap.1320
-rw-r--r--pullimap.md355
3 files changed, 384 insertions, 320 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7a56a47
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+all: pullimap.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)" | \
+ pandoc -sS -f json -t man -o "$@"
+
+install:
+
+clean:
+ rm -f pullimap.1
+
+.PHONY: all install clean
diff --git a/pullimap.1 b/pullimap.1
deleted file mode 100644
index 2d92e9d..0000000
--- a/pullimap.1
+++ /dev/null
@@ -1,320 +0,0 @@
-.TH PULLIMAP "1" "MARCH 2016" "PullIMAP" "User Commands"
-
-.SH NAME
-PullIMAP \- Pull mails from an IMAP mailbox and deliver them to a SMTP session
-
-.SH SYNOPSIS
-.B pullimap\fR [\fB--config=\fIFILE\fR] [\fB--idle\fR[\fB=\fISECONDS\fR]]
-[\fB--no-delivery\fR] [\fB--quiet\fR] \fISECTION\fR
-
-
-.SH DESCRIPTION
-.PP
-.B PullIMAP\fR retrieves messages from an IMAP mailbox and deliver them
-to a SMTP or LMTP transmission channel.
-It can also remove old messages after a configurable retention period.
-
-.PP
-A \fIstatefile\fR is used to keep track of the mailbox's UIDVALIDITY and
-UIDNEXT values. While \fBPullIMAP\fR is running, the \fIstatefile\fR is
-also used to keep track of UIDs being delivered, which avoids duplicate
-deliveries if the process is interrupted.
-See the \fBCONTROL FLOW\fR section below.
-
-.SH OPTIONS
-.TP
-.B \-\-config=\fR\fIFILE\fR
-Specify an alternate configuration file. Relative paths start from
-\fI$XDG_CONFIG_HOME\fR, or \fI~/.config\fR if the XDG_CONFIG_HOME
-environment variable is unset.
-
-.TP
-.B \fB\-\-idle\fR[\fB=\fR\fIseconds\fR]
-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.
-
-.TP
-.B \fB\-\-no\-delivery
-Update the \fIstatefile\fR, but skip SMTP/LMTP delivery. This is mostly
-useful for initializing the \fIstatefile\fR when migrating to
-\fBPullIMAP\fR from another equivalent program such as \fIgetmail\fR(1)
-or \fIfetchmail\fR(1).
-
-.TP
-.B \-q\fR, \fB\-\-quiet\fR
-Try to be quiet.
-
-.TP
-.B \-\-debug
-Turn on debug mode. Debug messages are written to the error output.
-Note that this include all IMAP traffic (except literals). Depending on
-the chosen authentication mechanism, this might include authentication
-credentials.
-
-.TP
-.B \-h\fR, \fB\-\-help\fR
-Output a brief help and exit.
-
-.TP
-.B \-\-version
-Show the version number and exit.
-
-.SH CONFIGURATION FILE
-
-Unless told otherwise by the \fB\-\-config=\fR\fIFILE\fR option,
-\fBPullIMAP\fR reads its configuration from
-\fI$XDG_CONFIG_HOME/pullimap\fR (or \fI~/.config/pullimap\fR if the
-XDG_CONFIG_HOME environment variable is unset) as an INI file.
-The syntax of the configuration file is a series of
-\fIOPTION\fR=\fIVALUE\fR lines organized under some \fI[SECTION]\fR;
-lines starting with a \(oq#\(cq or \(oq;\(cq character are ignored as
-comments.
-Valid options are:
-
-.TP
-.I statefile
-State file to use to keep track of the \fImailbox\fR's UIDVALIDITY and
-UIDNEXT values.
-Relative paths start from \fI$XDG_DATA_HOME/pullimap\fR, or
-\fI~/.local/share/pullimap\fR if the XDG_DATA_HOME environment variable
-is unset.
-(Default: \(lq\fISECTION\fR\)\(rq, where \fISECTION\fR is the section
-name of the option.)
-
-.TP
-.I mailbox
-The IMAP mailbox to pull messages from.
-Support for persistent message Unique Identifiers (UID) is required.
-(Default: \(lqINBOX\)\(rq.)
-
-.TP
-.I deliver\-method
-\fR\fIprotocol\fR:\fI[address]\fI\fR:\fIport\fR where to deliver
-messages. Both SMTP [RFC 5321] and LMTP [RFC 2030] are supported.
-(Default: \(lqsmtp:[127.0.0.1]:25\)\(rq.)
-
-.TP
-.I deliver\-ehlo
-Hostname to use in EHLO or LHLO commands.
-(Default: \(lq\fIlocalhost.localdomain\fR\)\(rq.)
-
-
-.TP
-.I deliver\-rcpt
-Message recipient.
-(Default: the username associated with the effective uid of the
-\fBpullimap\fR process.)
-
-.TP
-.I purge\-after
-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 12 hours.
-
-.TP
-.I type
-One of \(lqimap\(rq, \(lqimaps\(rq or \(lqtunnel\(rq.
-\fItype\fR=imap and \fItype\fR=imaps are respectively used for IMAP and
-IMAP over SSL/TLS connections over a INET socket.
-\fItype\fR=tunnel causes \fBPullIMAP\fR to open a pipe to a
-\fIcommand\fR instead of a raw socket.
-Note that specifying \fItype\fR=tunnel in the \(lq[remote]\(rq section
-makes the default \fIdatabase\fR to be \(lqlocalhost.db\(rq.
-(Default: \(lqimaps\(rq.)
-
-.TP
-.I host
-Server hostname, for \fItype\fR=imap and \fItype\fR=imaps.
-(Default: \(lqlocalhost\(rq.)
-
-.TP
-.I port
-Server port.
-(Default: \(lq143\(rq for \fItype\fR=imap, \(lq993\(rq for
-\fItype\fR=imaps.)
-
-.TP
-.I proxy
-An optional SOCKS proxy to use for TCP connections to the IMAP server
-(\fItype\fR=imap and \fItype\fR=imaps only), formatted as
-\(lq\fIprotocol\fR://[\fIuser\fR:\fIpassword\fR@]\fIproxyhost\fR[:\fIproxyport\fR]\(rq.
-If \fIproxyport\fR is omitted, it is assumed at port 1080.
-Only SOCKSv5 is supported, in two flavors: \(lqsocks5://\(rq to resolve
-\fIhostname\fR locally, and \(lqsocks5h://\(rq to let the proxy resolve
-\fIhostname\fR.
-
-.TP
-.I command
-Command to use for \fItype\fR=tunnel. Must speak the IMAP4rev1 protocol
-on its standard output, and understand it on its standard input.
-
-.TP
-.I STARTTLS
-Whether to use the \(lqSTARTTLS\(rq directive to upgrade to a secure
-connection. Setting this to \(lqYES\(rq for a server not advertising
-the \(lqSTARTTLS\(rq capability causes \fBPullIMAP\fR to immediately
-abort the connection.
-(Ignored for \fItype\fRs other than \(lqimap\(rq. Default: \(lqYES\(rq.)
-
-.TP
-.I auth
-Space\-separated list of preferred authentication mechanisms.
-\fBPullIMAP\fR uses the first mechanism in that list that is also
-advertised (prefixed with \(lqAUTH=\(rq) in the server's capability list.
-Supported authentication mechanisms are \(lqPLAIN\(rq and \(lqLOGIN\(rq.
-(Default: \(lqPLAIN LOGIN\(rq.)
-
-.TP
-.I username\fR, \fIpassword\fR
-Username and password to authenticate with. Can be required for non
-pre\-authenticated connections, depending on the chosen authentication
-mechanism.
-
-.TP
-.I compress
-Whether to use the IMAP COMPRESS extension [RFC4978] for servers
-advertising it.
-(Default: \(lqYES\(rq.)
-
-.TP
-.I null\-stderr
-Whether to redirect \fIcommand\fR's standard error to \(lq/dev/null\(rq
-for type \fItype\fR=tunnel.
-(Default: \(lqNO\(rq.)
-
-.TP
-.I SSL_protocols
-A space-separated list of SSL protocols to enable or disable (if
-prefixed with an exclamation mark \(oq!\(cq). Known protocols are
-\(lqSSLv2\(rq, \(lqSSLv3\(rq, \(lqTLSv1\(rq, \(lqTLSv1.1\(rq, and
-\(lqTLSv1.2\(rq. Enabling a protocol is a short-hand for disabling all
-other protocols.
-(Default: \(lq!SSLv2 !SSLv3\(rq, i.e., only enable TLSv1 and above.)
-
-.TP
-.I SSL_cipher_list
-The cipher list to send to the server. Although the server determines
-which cipher suite is used, it should take the first supported cipher in
-the list sent by the client. See \fBciphers\fR(1ssl) for more
-information.
-
-.TP
-.I SSL_fingerprint
-Fingerprint of the server certificate (or its public key) in the form
-\fIALGO\fR$\fIDIGEST_HEX\fR, where \fIALGO\fR is the used algorithm
-(default \(lqsha256\(rq).
-Attempting to connect to a server with a non-matching certificate
-fingerprint causes \fBPullIMAP\fR to abort the connection during the
-SSL/TLS handshake.
-
-.TP
-.I SSL_verify
-Whether to verify the server certificate chain.
-Note that using \fISSL_fingerprint\fR to specify the fingerprint of the
-server certificate is an orthogonal authentication measure as it ignores
-the CA chain.
-(Default: \(lqYES\(rq.)
-
-.TP
-.I SSL_CApath
-Directory to use for server certificate verification if
-\(lq\fISSL_verify\fR=YES\(rq.
-This directory must be in \(lqhash format\(rq, see \fBverify\fR(1ssl)
-for more information.
-
-.TP
-.I SSL_CAfile
-File containing trusted certificates to use during server certificate
-authentication if \(lq\fISSL_verify\fR=YES\(rq.
-
-.SH CONTROL FLOW
-\fBPullIMAP\fR opens the \fIstatefile\fR corresponding to a given
-configuration \fISECTION\fR with O_DSYNC to ensure that written data is
-flushed to the underlying hardware by the time \fIwrite\fR(2) returns.
-Moreover an exclusive lock is placed on the file descriptor immediately
-after opening to prevent multiple \fBpullimap\fR processes from
-accessing the \fIstatefile\fR concurrently.
-
-Each \fIstatefile\fR consists of a series of 32-bits big-endian
-integers. Usually there are only two integers:
-the first is the \fImailbox\fR's UIDVALIDITY value, and the second is
-the \fImailbox\fR's last seen UIDNEXT value (\fBPullIMAP\fR then assumes
-that all messages with UID smaller than this UIDNEXT value have already
-been retrieved and delivered).
-The IMAP4rev1 specification [RFC 3501] does not guaranty that untagged
-FETCH responses are sent ordered by UID in response of an UID FETCH
-command. Thus it would be unsafe for \fBPullIMAP\fR to update the
-UIDNEXT value in the \fIstatefile\fR while the UID FETCH command is
-progress.
-Instead, for each untagged FETCH response received while while the UID
-FETCH command is in progress, \fBPullIMAP\fR delivers the message BODY
-to the SMTP or LMTP server specified with \fIdeliver\-method\fR then
-appends the message UID to the \fIstatefile\fR. When the UID FETCH
-command eventually terminates, \fBPullIMAP\fR updates the UIDNEXT value
-in the \fIstatefile\fR and truncate the file down to 8 bytes.
-Keeping track of message UIDs as they are received avoids duplicate in
-the even of a crash or session loss while the UID FETCH command is in
-progress.
-
-In more details, \fBPullIMAP\fR works as follows:
-
-.nr step 1 1
-.IP \n[step]. 4
-Issue an UID FETCH command to retrieve message ENVELOPE and BODY (and
-UID) with UID bigger or equal than the UIDNEXT value found in the
-\fIstatefile\fR.
-While the UID FETCH command is in progress, perform the following
-for each untagged FETCH response sent by the server:
-.RS
-\(bu
-if no SMTP/LMTP transmission channel was opened, open one to the server
-specified with \fIdeliver\-method\fR and send an EHLO (or LHO) command
-with the domain given by \fIdeliver\-ehlo\fR;
-.br
-\(bu
-perform a mail transaction (using SMTP pipelining [RFC 2920] if
-possible) to send the retrieved message BODY to the SMTP or LMTP
-session; and
-.br
-\(bu
-append the message UID to the \fIstatefile\fR.
-.RE
-
-.IP \n+[step].
-If a SMTP/LMTP transmission channel was opened, send a QUIT command to
-close it gracefully.
-
-.IP \n+[step].
-Issue an UID STORE command to mark all retrieved messages (and stalled
-UIDs found in the \fIstatefile\fR after the UIDNEXT value) as \\Seen.
-
-.IP \n+[step].
-Update the \fIstatefile\fR with the new UIDNEXT value.
-
-.IP \n+[step].
-Truncate the \fIstatefile\fR down to 8 bytes (so that it contains only
-two 32-bits integers, respectively the \fImailbox\fR's UIDVALIDITY and
-UIDNEXT values).
-
-.IP \n+[step].
-If \fB\-\-idle\fR was set, issue an IDLE command; stop idling and go
-back to step 1. whenever a new message is received.
-
-.SH AUTHOR
-.ie \n[www-html] \{\
- Written by
-. MTO guilhem@fripost.org "Guilhem Moulin" .
-\}
-.el \{\
- Written by Guilhem Moulin
-. MT guilhem@fripost.org
-. ME .
-\}
diff --git a/pullimap.md b/pullimap.md
new file mode 100644
index 0000000..54c6ce5
--- /dev/null
+++ b/pullimap.md
@@ -0,0 +1,355 @@
+% pullimap(1)
+% [Guilhem Moulin](mailto:guilhem@fripost.org)
+% March 2016
+
+Name
+====
+
+PullIMAP - Pull mails from an IMAP mailbox and deliver them to a SMTP
+session
+
+Synopsis
+========
+
+`pullimap` [**\-\-config=***FILE*] [**\-\-idle**[**=***SECONDS*]]
+[**\-\-no-delivery**] [**\-\-quiet**] *SECTION*
+
+Description
+===========
+
+`pullimap` retrieves messages from an IMAP mailbox and deliver them to a
+SMTP or LMTP transmission channel. It can also remove old messages
+after a configurable retention period.
+
+A *statefile* is used to keep track of the mailbox's `UIDVALIDITY` and
+`UIDNEXT` values. While `pullimap` is running, the *statefile* is also
+used to keep track of UIDs being delivered, which avoids duplicate
+deliveries in case the process is interrupted.
+See the [**Control flow**](#control-flow) section below for details.
+
+Options
+=======
+
+`--config=`*FILE*
+
+: Specify an alternate configuration file. Relative paths start from
+ *$XDG_CONFIG_HOME*, or *~/.config* if the `XDG_CONFIG_HOME`
+ environment variable is unset.
+
+`--idle`[`=`*seconds*]
+
+: Don't exit after a successful poll. Instead, keep the connection open
+ and issue `IDLE` commands (require an IMAP server supporting [RFC
+ 2177]) to watch for updates in the mailbox. This also enables
+ `SO_KEEPALIVE` on the socket. Each `IDLE` command is terminated after
+ at most *seconds* (29 minutes by default) to avoid being logged out
+ for inactivity.
+
+`--no-delivery`
+
+: Update the *statefile*, but skip SMTP/LMTP delivery. This is mostly
+ useful for initializing the *statefile* when migrating to
+ `pullimap` from another similar program such as [`fetchmail`(1)] or
+ [`getmail`(1)].
+
+`-q`, `--quiet`
+
+: Try to be quiet.
+
+`--debug`
+
+: Turn on debug mode. Debug messages are written to the error output.
+ Note that this include all IMAP traffic (except literals). Depending
+ on the chosen authentication mechanism, this might include
+ authentication credentials.
+
+`-h`, `--help`
+
+: Output a brief help and exit.
+
+`--version`
+
+: Show the version number and exit.
+
+
+Configuration file
+==================
+
+Unless told otherwise by the `--config=FILE` option, `pullimap` reads
+its configuration from *$XDG_CONFIG_HOME/pullimap* (or
+*~/.config/pullimap* if the `XDG_CONFIG_HOME` environment variable is
+unset) as an [INI file].
+The syntax of the configuration file is a series of `OPTION=VALUE`
+lines organized under some `[SECTION]`; lines starting with a ‘#’ or
+‘;’ character are ignored as comments.
+Valid options are:
+
+*statefile*
+
+: State file to use to keep track of the *mailbox*'s `UIDVALIDITY` and
+ `UIDNEXT` values. Relative paths start from
+ *$XDG_DATA_HOME/pullimap*, or *~/.local/share/pullimap* if the
+ `XDG_DATA_HOME` environment variable is unset.
+ (Default: the parent section name of the option.)
+
+*mailbox*
+
+: The IMAP mailbox to pull messages from.
+ Support for persistent message Unique Identifiers (UID) is required.
+ (Default: `INBOX`.)
+
+*deliver-method*
+
+: `PROTOCOL:[ADDRESS]:PORT` where to deliver messages. Both [SMTP][RFC
+ 5321] and [LMTP][RFC 2033] servers are supported, and [SMTP
+ pipelining][RFC 2920] is used when possible.
+ (Default: `smtp:[127.0.0.1]:25`.)
+
+*deliver-ehlo*
+
+: Hostname to use in `EHLO` or `LHLO` commands.
+ (Default: `localhost.localdomain`.)
+
+*deliver-rcpt*
+
+: Message recipient.
+ (Default: the username associated with the effective uid of the
+ `pullimap` process.)
+
+*purge-after*
+
+: Retention period (in days), after which messages are removed from the
+ IMAP server. (The value is at best 24h accurate due to the IMAP
+ `SEARCH` criterion ignoring time and timezone.)
+ If *purge-after* is set to `0` then messages are deleted immediately
+ after delivery. Otherwise `pullimap` issues an IMAP `SEARCH` command
+ to list old messages; if `--idle` is set then the `SEARCH` command is
+ issued again every 12 hours.
+
+*type*
+
+: One of `imap`, `imaps` or `tunnel`.
+ `type=imap` and `type=imaps` are respectively used for IMAP and IMAP
+ over SSL/TLS connections over a INET socket.
+ `type=tunnel` causes `pullimap` to open a pipe to a *command* instead
+ of a raw socket.
+ (Default: `imaps`.)
+
+*host*
+
+: Server hostname, for `type=imap` and `type=imaps`.
+ (Default: `localhost`.)
+
+*port*
+
+: Server port.
+ (Default: `143` for `type=imap`, `993` for
+ `type=imaps`.)
+
+*proxy*
+
+: An optional SOCKS proxy to use for TCP connections to the IMAP server
+ (`type=imap` and `type=imaps` only), formatted as
+ `PROTOCOL://[USER:PASSWORD@]PROXYHOST[:PROXYPORT]`.
+ If `PROXYPORT` is omitted, it is assumed at port 1080.
+ Only [SOCKSv5][RFC 1928] is supported (with optional
+ [username/password authentication][RFC 1929]), in two flavors:
+ `socks5://` to resolve *hostname* locally, and `socks5h://` to let the
+ proxy resolve *hostname*.
+
+*command*
+
+: Command to use for `type=tunnel`. Must speak the [IMAP4rev1
+ protocol][RFC 3501] on its standard output, and understand it on its
+ standard input.
+
+*STARTTLS*
+
+: Whether to use the [`STARTTLS`][RFC 2595] directive to upgrade to a
+ secure connection. Setting this to `YES` for a server not advertising
+ the `STARTTLS` capability causes `pullimap` to immediately abort the
+ connection.
+ (Ignored for *type*s other than `imap`. Default: `YES`.)
+
+*auth*
+
+: Space-separated list of preferred authentication mechanisms.
+ `pullimap` uses the first mechanism in that list that is also
+ advertised (prefixed with `AUTH=`) in the server's capability list.
+ Supported authentication mechanisms are `PLAIN` and `LOGIN`.
+ (Default: `PLAIN LOGIN`.)
+
+*username*, *password*
+
+: Username and password to authenticate with. Can be required for non
+ pre-authenticated connections, depending on the chosen authentication
+ mechanism.
+
+*compress*
+
+: Whether to use the [`IMAP COMPRESS` extension][RFC 4978] for servers
+ advertising it. (Default: `YES`.)
+
+*null-stderr*
+
+: Whether to redirect *command*'s standard error to `/dev/null` for type
+ `type=tunnel`. (Default: `NO`.)
+
+*SSL_protocols*
+
+: A space-separated list of SSL protocols to enable or disable (if
+ prefixed with an exclamation mark `!`. Known protocols are
+ `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, and `TLSv1.2`. Enabling a
+ protocol is a short-hand for disabling all other protocols.
+ (Default: `!SSLv2 !SSLv3`, i.e., only enable TLSv1 and above.)
+
+*SSL_cipher_list*
+
+: The cipher list to send to the server. Although the server determines
+ which cipher suite is used, it should take the first supported cipher
+ in the list sent by the client. See [`ciphers`(1ssl)] for more
+ information.
+
+*SSL_fingerprint*
+
+: Fingerprint of the server certificate (or its public key) in the form
+ `ALGO$DIGEST_HEX`, where `ALGO` is the used algorithm (default
+ `sha256`).
+ Attempting to connect to a server with a non-matching certificate
+ fingerprint causes `pullimap` to abort the connection during the
+ SSL/TLS handshake.
+
+*SSL_verify*
+
+: Whether to verify the server certificate chain.
+ Note that using *SSL_fingerprint* to specify the fingerprint of the
+ server certificate is an orthogonal authentication measure as it
+ ignores the CA chain.
+ (Default: `YES`.)
+
+*SSL_CApath*
+
+: Directory to use for server certificate verification if
+ `SSL_verify=YES`.
+ This directory must be in “hash format”, see [`verify`(1ssl)] for
+ more information.
+
+*SSL_CAfile*
+
+: File containing trusted certificates to use during server certificate
+ authentication if `SSL_verify=YES`.
+
+Control flow
+============
+
+`pullimap` opens the *statefile* corresponding to a given configuration
+*SECTION* with `O_DSYNC` to ensure that written data is flushed to the
+underlying hardware by the time [`write`(2)] returns. Moreover an
+exclusive lock is placed on the file descriptor immediately after
+opening to prevent multiple `pullimap` processes from accessing the
+*statefile* concurrently.
+
+Each *statefile* consists of a series of 32-bits big-endian integers.
+Usually there are only two integers: the first is the *mailbox*'s
+`UIDVALIDITY` value, and the second is the *mailbox*'s last seen
+`UIDNEXT` value (`pullimap` then assumes that all messages with UID
+smaller than this `UIDNEXT` value have already been retrieved and
+delivered).
+The [IMAP4rev1 specification][RFC 3501] does not guaranty that untagged
+`FETCH` responses are sent ordered by UID in response to an `UID FETCH`
+command. Thus it would be unsafe for `pullimap` to update the `UIDNEXT`
+value in its *statefile* while the `UID FETCH` command is progress.
+Instead, for each untagged `FETCH` response received while the `UID
+FETCH` command is in progress, `pullimap` delivers the message `BODY` to
+the SMTP or LMTP server (specified with *deliver-method*) then appends
+the message UID to the *statefile*.
+When the `UID FETCH` command eventually terminates, `pullimap` updates
+the `UIDNEXT` value in the *statefile* and truncate the file down to 8
+bytes. Keeping track of message UIDs as they are received avoids
+duplicate in the event of a crash or connection loss while the `UID
+FETCH` command is in progress.
+
+In more details, `pullimap` works as follows:
+
+ 1. Issue an `UID FETCH` command to retrieve message `ENVELOPE` and
+ `BODY` (and `UID`) with UID bigger or equal than the `UIDNEXT` value
+ found in the *statefile*.
+ While the `UID FETCH` command is in progress, perform the following
+ for each untagged `FETCH` response sent by the server:
+
+ i) if no SMTP/LMTP transmission channel was opened, open one to the
+ server specified with *deliver-method* and send an `EHLO` (or
+ `LHO`) command with the domain specified by *deliver-ehlo*;
+
+ ii) perform a mail transaction (using [SMTP pipelining][RFC 2920] if
+ possible) to send the retrieved message BODY to the SMTP or LMTP
+ session; and
+
+ ii) append the message UID to the *statefile*.
+
+ 2. If a SMTP/LMTP transmission channel was opened, send a `QUIT` command
+ to terminate it gracefully.
+
+ 3. Issue an `UID STORE` command to mark all retrieved messages (and
+ stalled UIDs found in the *statefile* after the eigth byte) as
+ `\Seen`.
+
+ 4. Update the *statefile* with the new UIDNEXT value (bytes 5-8).
+
+ 5. Truncate the *statefile* down to 8 bytes (so that it contains only
+ two 32-bits integers, respectively the *mailbox*'s current
+ `UIDVALIDITY` and `UIDNEXT` values).
+
+ 6. If `--idle` was set, issue an `IDLE` command; stop idling and go
+ back to step 1. whenever a new message is received.
+
+Standards
+=========
+
+ * M. Leech, M. Ganis, Y. Lee, R. Kuris, D. Koblas and L. Jones,
+ _SOCKS Protocol Version 5_,
+ [RFC 1928], March 1996
+ * M. Leech, _Username/Password Authentication for SOCKS V5_,
+ [RFC 1929], March 1996
+ * J. Myers, _Local Mail Transfer Protocol_,
+ [RFC 2033], October 1996
+ * J. Myers, _IMAP4 non-synchronizing literals_,
+ [RFC 2088], January 1997
+ * B. Leiba, _IMAP4 IDLE command_,
+ [RFC 2177], June 1997
+ * C. Newman, _Using TLS with IMAP, POP3 and ACAP_,
+ [RFC 2595], June 1999
+ * N. Freed, _SMTP Service Extension for Command Pipelining_,
+ [RFC 2920], September 2000
+ * M. Crispin, _Internet Message Access Protocol - Version 4rev1_,
+ [RFC 3501], March 2003
+ * M. Crispin,
+ _Internet Message Access Protocol (IMAP) - UIDPLUS extension_,
+ [RFC 4315], December 2005
+ * A. Gulbrandsen, _The IMAP COMPRESS Extension_,
+ [RFC 4978], August 2007
+ * R. Siemborski and A. Gulbrandsen, _IMAP Extension for Simple
+ Authentication and Security Layer (SASL) Initial Client Response_,
+ [RFC 4959], September 2007
+ * J. Klensin, _Simple Mail Transfer Protocol_,
+ [RFC 5321], October 2008
+
+[RFC 4315]: https://tools.ietf.org/html/rfc4315
+[RFC 2177]: https://tools.ietf.org/html/rfc2177
+[RFC 2595]: https://tools.ietf.org/html/rfc2595
+[RFC 4959]: https://tools.ietf.org/html/rfc4959
+[RFC 2088]: https://tools.ietf.org/html/rfc2088
+[RFC 5321]: https://tools.ietf.org/html/rfc5321
+[RFC 2033]: https://tools.ietf.org/html/rfc2033
+[RFC 2920]: https://tools.ietf.org/html/rfc2920
+[RFC 3501]: https://tools.ietf.org/html/rfc3501
+[RFC 4978]: https://tools.ietf.org/html/rfc4978
+[RFC 1928]: https://tools.ietf.org/html/rfc1928
+[RFC 1929]: https://tools.ietf.org/html/rfc1929
+
+[INI file]: https://en.wikipedia.org/wiki/INI_file
+[`fetchmail`(1)]: http://www.fetchmail.info/
+[`getmail`(1)]: http://pyropus.ca/software/getmail/
+[`write`(2)]: http://man7.org/linux/man-pages/man2/write.2.html
+[`ciphers`(1ssl)]: https://www.openssl.org/docs/manmaster/apps/ciphers.html
+[`verify`(1ssl)]: https://www.openssl.org/docs/manmaster/apps/verify.html