interimap(1)
π interimap β the manual page, but make it a group chat π
okay bestie, sit down, hydrate, and let me tell you about interimap β short for InterIMAP. It's giving Fast bidirectional synchronization for QRESYNC-capable IMAP servers and honestly? It ate. π¦
β¨ SYNOPSIS β¨
interimap [OPTION ...] [COMMAND] [MAILBOX ...]
that's the whole vibe. options, maybe a command, maybe some mailboxes. simple. iconic. π
πΈ DESCRIPTION πΈ
so what does it actually DO? interimap performs stateful synchronization between two IMAP4rev1 servers. two servers. talking to each other. through this little program. the way that it manages to do this is via the QRESYNC IMAP extension β and for convenience reasons, the servers also have to support the LIST-EXTENDED, LIST-STATUS (or NOTIFY) and UIDPLUS IMAP extensions. go peek at the supported extensions section below if you want the receipts. π
Stateful synchronization is only possible for mailboxes supporting persistent message Unique Identifiers (UID) and persistent storage of mod-sequences (MODSEQ) β and fr fr, any non-compliant mailbox will cause interimap to abort. no soft launch, no negotiation, it's just done. π
and here's the tea: because UIDs are allocated not by the client but by the server, interimap has to keep track of associations between local and remote UIDs for each mailbox. the synchronization state of a mailbox is literally just its UIDNEXT and HIGHESTMODSEQ values on each server. from there it assumes that:
- each message with UID smaller than
UIDNEXThas been replicated to the other server, and - the metadata (like flags) of each message with MODSEQ at most
HIGHESTMODSEQhas been synchronized.
conceptually the synchronization algorithm is derived from RFC 4549 with the RFC 7162 (sec. 6) amendments, and it works like this:
SELECT(on both servers) a mailbox the currentUIDNEXTorHIGHESTMODSEQvalues of which differ from the values found in the database (for either server). Use theQRESYNC SELECTparameter from RFC 7162 to list changes (vanished messages and flag updates) sinceHIGHESTMODSEQto messages with UID smaller thanUIDNEXT.- Propagate these changes onto the other server: get the corresponding UIDs from the database, then:
a. issue a UID STORE command, followed by UID EXPUNGE, to remove messages that have not already been deleted on both servers; and
b. issue some UID STORE commands to propagate flag updates (send a single command for each flag list in order the reduce the number of round trips).
(Conflicts may occur if the metadata of a message has been updated on both servers with different flag lists; in that case, interimap issues a warning and updates the message on each server with the union of both flag lists.) Repeat this step if the server sent some updates in the meantime. Otherwise, update the HIGHESTMODSEQ value in the database.
- Process new messages (if the current
UIDNEXTvalue of the mailbox differs from the one found in the database) by issuing aUID FETCHcommand; process each received message on-the-fly by issuing anAPPENDcommand with the message'sRFC822body,FLAGSandINTERNALDATE. Repeat this step if the server received new messages in the meantime. Otherwise, update theUIDNEXTvalue in the database. Go back to step 2 if the server sent some metadata (such as flag) updates in the meantime. - Go back to step 1 to proceed with the next unsynchronized mailbox.
likeβ¦ it's a loop bestie. a beautiful, careful, RFC-respecting loop. π
π COMMANDS π
by default, interimap synchronizes each mailbox listed by the LIST "" "*" IMAP command. and yes, the list-mailbox, list-select-opts and ignore-mailbox options from the configuration file can be used to shrink that list and save bandwidth β we love an efficient queen. β¨
but if some extra argument are provided on the command line, interimap ignores these options and synchronizes the given MAILBOXes instead. and ngl, each MAILBOX is taken "as is" β in particular, it must be UTF-7 encoded, unquoted, and the list wildcards * and % are passed verbatim to the IMAP server. no editing, no translating, no vibes-based guessing. π«Ά
also: if the local and remote hierarchy delimiter differ, then within the MAILBOX names the local delimiter should be used (it is transparently substituted for remote commands and responses). so use yours, it handles the translation. π
if the synchronization was interrupted during a previous run while some messages were being replicated (but before the UIDNEXT or HIGHESTMODSEQ values have been updated), interimap performs a "full synchronization" on theses messages: downloading the whole UID and flag lists on each servers allows interimap to detect messages that have been removed or for which their flags have changed in the meantime. finally, after propagating the offline changes for these messages, interimap resumes the synchronization for the rest of the mailbox. it picks itself back up. main character energy. π
specifying one of the commands below makes interimap perform an action other than the default QRESYNC-based synchronization. ok so:
--repair [MAILBOX ...]β list the database anomalies and try to repair them. (Consider only the given *MAILBOX*es if non-optional arguments are provided.) This is done by performing a so-called "full synchronization", namely: 1/ download all UIDs along with their flag list both from the local and remote servers; 2/ ensure that each entry in the database corresponds to an existing UID; and 3/ ensure that both flag lists match. Any message found on a server but not in the database is replicated on the other server (which in the worst case, might yield a message duplicate). Flag conflicts are solved by updating each message to the union of both lists.--delete MAILBOX [MAILBOX ...]β delete the given MAILBOXes on each target (by default each server plus the database, unless--targetspecifies otherwise) where it exists. Note that per the IMAP4rev1 standard deletion is not recursive. Thus MAILBOX's children are not deleted.--rename SOURCE DESTβ rename the mailbox SOURCE to DEST on each target (by default each server plus the database, unless--targetspecifies otherwise) where it exists.interimapaborts if DEST already exists on either target. Note that per the IMAP4rev1 standard renaming is recursive. Thus SOURCE's children are moved to become DEST's children instead.
π OPTIONS π
--config=FILEβ Specify an alternate configuration file. Relative paths start from$XDG_CONFIG_HOME/interimap, or~/.config/interimapif theXDG_CONFIG_HOMEenvironment variable is unset.--target={local,remote,database}β Limit the scope of a--deleteor--renamecommand to the given target. Can be repeated to act on multiple targets. By default all three targets are considered.--watch[=seconds]β Don't exit after a successful synchronization. Instead, keep synchronizing forever. Sleep for the given number of seconds (by default 1 minute if--notifyis unset, and 15 minutes if--notifyis set) between two synchronizations. Setting this options enablesSO_KEEPALIVEon the socket for types other than tunnel.--notifyβ Whether to use the IMAPNOTIFYextension to instruct the server to automatically send updates to the client. (Both local and remote servers must support RFC 5465 for this to work.) This greatly reduces IMAP traffic sinceinterimapcan rely on server notifications instead of manually polling for updates. If the connection remains idle for 15 minutes (configurable with--watch), theninterimapsends aNOOPcommand to avoid being logged out for inactivity.-q,--quietβ Try to be quiet. π€«--debugβ Turn on debug mode. Debug messages, which includes all IMAP traffic besides literals, are written to the given logfile. TheLOGINandAUTHENTICATEcommands are however redacted (in order to avoid disclosing authentication credentials) unless the--debugflag is set multiple times.-h,--helpβ Output a brief help and exit.--versionβ Show the version number and exit.
π CONFIGURATION FILE π
unless told otherwise by the --config=FILE command-line option, interimap reads its configuration from $XDG_CONFIG_HOME/interimap/config (or ~/.config/interimap/config 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. the [local] and [remote] sections define the two IMAP servers to synchronize. valid options are:
databaseβ SQLite version 3 database file to use to keep track of associations between local and remote UIDs, as well as theUIDVALIDITY,UIDNEXTandHIGHESTMODSEQof each known mailbox on both servers. Relative paths start from$XDG_DATA_HOME/interimap, or~/.local/share/interimapif theXDG_DATA_HOMEenvironment variable is unset. This option is only available in the default section. (Default:HOST.db, whereHOSTis taken from the[remote]or[local]sections, in that order.)list-referenceβ An optional "reference name" to use for the initialLISTcommand, indicating the context in which the MAILBOXes are interpreted. For instance, by specifyinglist-reference=perso/in the[local]section, MAILBOX names are interpreted relative toperso/on the local server; in other words the remote mailbox hierarchy is mapped to theperso/sub-hierarchy on the local server. This is useful for synchronizing multiple remote servers against different namespaces belonging to the same local IMAP server (using a differentinterimapinstance for each local namespace β remote synchronization).
(Note that if the reference name is not a level of mailbox hierarchy and/or does not end with the hierarchy delimiter, by RFC 3501 its interpretation by the IMAP server is implementation-dependent.)
to be continued, bestieβ¦ π
list-mailboxβ the space-separated list of mailbox patterns that gets used when interimap fires off its very firstLISTcommand. (It gets overridden by theMAILBOXesyou hand over as command-line arguments, bestie β CLI always wins.) Names that contain special characters like spaces or brackets need to be wrapped in double quotes. And inside those double quotes you can use C-style backslash escape sequences (\tfor an horizontal tab,\nfor a new line,\\for a backslash, etc.), plus hexadecimal escape sequences like\xHH. Also, non-ASCII names must be UTF-7 encoded. π
Two wildcards are in the mix, and they're passed verbatim straight to the IMAP server: a * character matches zero or more characters, while a % character matches zero or more characters up to the hierarchy delimiter. Hard-coding the hierarchy delimiter in this setting is not advised β the server might silently change it at some point. Use a null character instead. For instance, if list-mailbox is set to "foo\x00bar" then, assuming the hierarchy delimiter is /, only the mailbox named foo/bar is considered for synchronization.
This option is only available in the default section. (The default pattern, *, matches all visible mailboxes on the server.) π¦
list-select-optsβ an optional space-separated list of selectors for that initialLISTcommand. (Requires a server supporting the LIST-EXTENDED IMAP extension, so vibe check your server first.) Useful values areSUBSCRIBED(to list only subscribed mailboxes),REMOTE(to also list remote mailboxes on a server supporting mailbox referrals), andRECURSIVEMATCH(to list parent mailboxes with children matching one of the abovelist-mailboxpatterns). This option is only available in the default section.ignore-mailboxβ an optional Perl Compatible Regular Expressions (PCRE) covering mailboxes to exclude. Any (UTF-7 encoded and unquoted) mailbox listed in the initialLISTresponses is ignored if it matches the given expression, after trimming the reference names and substituting the hierarchy delimiter with the null character. For instance, specifying^virtual(?:\x00|$)excludes the mailbox named βvirtualβ as well as its descendants. Note that theMAILBOXesgiven as command-line arguments bypass the check and are always considered for synchronization. This option is only available in the default section.logfileβ a file name to use for logging debug and informational messages. (By default these messages are written to the error output.) This option is only available in the default section.log-prefixβ a printf(3)-like format string used as a prefix for each log message. The interpreted sequences are%nand%m, expanding respectively to the component name (local/remote) and to the name of the mailbox relevant for the log entry. Conditions on a specifier%Xcan be obtained with%?X?then?or%?X?then&else?, which expands tothenif the%Xspecifier expands to a non-empty string, and toelse(or the empty string if there is no else condition) if it doesn't. Literal%characters need to be escaped as%%, while&,?and\characters need to be\-escaped. (Default:%?n?%?m?%n(%m)&%n?: ?.)typeβ one ofimap,imapsortunnel.type=imapandtype=imapsare respectively used for IMAP and IMAP over SSL/TLS connections over an INET socket.type=tunnelcauses interimap to create an unnamed pair of connected sockets for inter-process communication with a command instead of opening a network socket. Note that specifyingtype=tunnelin the[remote]section makes the default database belocalhost.db. (Default:imaps.)hostβ server hostname or IP address, fortype=imapandtype=imaps. The value can optionally be enclosed in square brackets to force its interpretation as an IP literal (hence skip name resolution). (Default:localhost.)portβ server port. (Default:143fortype=imap,993fortype=imaps.)proxyβ optional SOCKS proxy to use for TCP connections to the IMAP server (type=imapandtype=imapsonly), formatted asPROTOCOL://[USER:PASSWORD@]PROXYHOST[:PROXYPORT]. IfPROXYPORTis omitted, it is assumed at port1080. Only SOCKSv5 is supported (with optional username/password authentication), in two flavors:socks5://to resolve hostname locally, andsocks5h://to let the proxy resolve hostname. π§commandβ command to use fortype=tunnel. It must speak the IMAP4rev1 protocol on its standard output, and understand it on its standard input. The value is passed to/bin/sh -cif it contains shell metacharacters; otherwise it is split into words and the resulting list is passed to execvp(3).STARTTLSβ whether to use the STARTTLS directive to upgrade to a secure connection. Setting this toYESfor a server that isn't advertising the STARTTLS capability causes interimap to immediately abort the connection. (Ignored for types other thanimap. Default:YES.)authβ space-separated list of preferred authentication mechanisms. interimap uses the first mechanism in that list that is also advertised (prefixed withAUTH=) in the server's capability list. Supported authentication mechanisms arePLAINandLOGIN. (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 for servers advertising it. (Default:NOfor the[local]section,YESfor the[remote]section.)null-stderrβ whether to redirect the command's standard error to/dev/nullfortype=tunnel. This option is ignored when the--debugflag is set. (Default:NO.)SSL_protocolsβ space-separated list of SSL/TLS protocol versions to explicitly enable (or disable if prefixed with an exclamation mark!). Potentially known protocols areSSLv2,SSLv3,TLSv1,TLSv1.1,TLSv1.2, andTLSv1.3, depending on the OpenSSL version used. Enabling a protocol is a short-hand for disabling all other protocols.
DEPRECATED: UseSSL_protocol_minand/orSSL_protocol_maxinstead. π
SSL_protocol_min,SSL_protocol_maxβ set the minimum resp. maximum SSL/TLS protocol version to use for the connection. Potentially recognized values areSSLv3,TLSv1,TLSv1.1,TLSv1.2, andTLSv1.3, depending on the OpenSSL version used.SSL_cipherlist,SSL_ciphersuitesβ sets the TLSv1.2 and below cipher list resp. the TLSv1.3 cipher suites. The combination of these lists is sent to the server, which then determines which cipher to use (normally the first supported one from the list sent by the client). The default suites depend on the OpenSSL version and its configuration, see ciphers(1ssl) for more information.SSL_fingerprintβ space-separated list of acceptable fingerprints for the server certificate's Subject Public Key Info, in the form[ALGO$]DIGEST_HEXwhereALGOis the digest algorithm (by defaultsha256). Attempting to connect to a server with a non-matching certificate SPKI fingerprint causes interimap to abort the connection during the SSL/TLS handshake. The following command can be used to compute the SHA-256 digest of a certificate's Subject Public Key Info:
$ openssl x509 -in /path/to/server/certificate.pem -pubkey \
| openssl pkey -pubin -outform DER \
| openssl dgst -sha256
Specifying multiple digest values can be useful in key rollover scenarios and/or when the server supports certificates of different types (for instance a dual-cert RSA/ECDSA setup). In that case the connection is aborted when none of the specified digests matches. π₯
SSL_verifyβ whether to 1/ verify the server certificate chain; and 2/ match its Subject Alternative Name (SAN) or Subject CommonName (CN) against the value of thehostoption. (Default:YES.)
Note that using SSL_fingerprint to specify the fingerprint of the server certificate provides an independent server authentication measure as it pins directly its key material and ignore its chain of trust. π
SSL_CAfileβ file containing trusted certificates to use during server certificate verification whenSSL_verify=YES.
Trusted CA certificates are loaded from the default system locations unless one (or both) of SSL_CAfile or SSL_CApath is set.
SSL_CApathβ directory to use for server certificate verification whenSSL_verify=YES. This directory must be in βhash formatβ, see verify(1ssl) for more information.
Trusted CA certificates are loaded from the default system locations unless one (or both) of SSL_CAfile or SSL_CApath is set.
SSL_hostnameβ name to use for the TLS SNI (Server Name Indication) extension. The default value is taken from thehostoption when it is a hostname, and to the empty string when it is an IP literal. SettingSSL_hostnameto the empty string explicitly disables SNI.
π SUPPORTED EXTENSIONS π
interimap takes advantage of servers supporting the following extensions to the IMAP4rev1 protocol (those marked as βrecommendedβ give the most significant performance gain β the way that those three just hit different):
- LITERAL+ (RFC 2088, recommended); β
- MULTIAPPEND (RFC 3502, recommended); β
- COMPRESS=DEFLATE (RFC 4978, recommended); β
- NOTIFY (RFC 5465);
- SASL-IR (RFC 4959); and
- UNSELECT (RFC 3691).
π KNOWN BUGS AND LIMITATIONS π
okay bestie, sit down, we gotta talk about the messy parts. not to be dramatic but these are the things that will bite you:
- Using
interimapon two identical servers with a non-existent or empty database will duplicate each message, because there's no local β remote UID association. (If that happens, an external tool likedoveadm-deduplicate(1)can weed them out.) So when you're migrating tointerimapfrom some other synchronization solution, you need to manually empty the mail store on one end first. yes literally. empty it. π interimapis single threaded and does not use IMAP command pipelining. Synchronization could be faster if independent commands (like the initialLISTandSTATUScommands) were sent to both servers in parallel, and, for a given server, if independent commands (like flag updates) were sent in a pipeline. so rn it's giving "one thing at a time" energy. π- Because the IMAP protocol has no specific response code for when a message is moved to another mailbox (whether that's via the
MOVEcommand from RFC 6851, or viaCOPY+STORE+EXPUNGE), moving a message makesinterimapbelieve it was deleted β while another one (which gets replicated again) was added to the other mailbox in the meantime. π - Because the IMAP protocol gives clients no way to tell whether a disappeared mailbox was deleted or renamed,
interimapaborts when a known mailbox disappears from one server but not the other. Use the--delete(resp.--rename) command instead to delete (resp. rename) the mailbox on both servers and insideinterimap's internal database. don't just yolo a rename on one side, bestie. π PLAINandLOGINare the only authentication mechanisms currently supported. that's the whole list. no cap.interimapwill probably not work with non RFC-compliant servers. In particular, no work-around is currently implemented beside the tunables in the configuration file. Also, few IMAP servers have been tested so far. so likeβ¦ good luck out there π«Ά
π STANDARDS π
the receipts, the lore, the source material. every single one:
- 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, IMAP4 non-synchronizing literals, RFC 2088, January 1997.
- D. Goldsmith and M. Davis, A Mail-Safe Transformation Format of Unicode, RFC 2152, May 1997.
- C. Newman, Using TLS with IMAP, POP3 and ACAP, RFC 2595, June 1999.
- M. Crispin, Internet Message Access Protocol - Version 4rev1, RFC 3501, March 2003.
- M. Crispin, Internet Message Access Protocol (IMAP) - MULTIAPPEND Extension, RFC 3502, March 2003.
- A. Melnikov, Internet Message Access Protocol (IMAP) UNSELECT command, RFC 3691, February 2004.
- M. Crispin, Internet Message Access Protocol (IMAP) - UIDPLUS extension, RFC 4315, December 2005.
- A. Melnikov, Synchronization Operations for Disconnected IMAP4 Clients, RFC 4549, June 2006.
- 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.
- A. Gulbrandsen and A. Melnikov, The IMAP ENABLE Extension, RFC 5161, March 2008.
- B. Leiba and A. Melnikov, Internet Message Access Protocol version 4 - LIST Command Extensions, RFC 5258, June 2008.
- A. Gulbrandsen, C. King and A. Melnikov, The IMAP NOTIFY Extension, RFC 5465, February 2009.
- A. Melnikov and T. Sirainen, IMAP4 Extension for Returning STATUS Information in Extended LIST, RFC 5819, March 2010.
- A. Gulbrandsen and N. Freed, Internet Message Access Protocol (IMAP) - MOVE Extension, RFC 6851, January 2013.
- A. Melnikov and D. Cridland, IMAP Extensions: Quick Flag Changes Resynchronization (CONDSTORE) and Quick Mailbox Resynchronization (QRESYNC), RFC 7162, May 2014.
like, the reading list is extensive. academia really said "here's 18 papers, enjoy." πβ¨
π BUGS AND FEEDBACK π
Found a bug? Got a feature request? Don't suffer in silence, bestie. Bugs or feature requests for interimap should be filed with the Debian project's bug tracker at <https://www.debian.org/Bugs/>. that's the move. π«Ά
π SEE ALSO π
There's a getting started guide, and it comes in two flavours:
- locally, at
<file:///usr/share/doc/interimap/getting-started.md.gz> - online, at
<https://guilhem.org/interimap/getting-started.html>
go read it, it's giving helpful. π
π AUTHORS π
Guilhem Moulin
and that's a wrap on interimap(1), bestie!! πβ¨ this gorgeous little page is from July 2015, and yeah β interimap(1) is the section, iconic as ever. go sync some mail, but likeβ¦ carefully. ππ¦
π¦ where this page comes from
- debian trixie: interimap 0.5.8-1 Β· GPL-3.0-or-later
- ubuntu questing: interimap 0.5.8-1
- ubuntu resolute: interimap 0.5.8-2 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms