Since this is used in an except calse, we first don't mask the real cause and
raise the original error.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
By default, OfflineIMAP catches SIGTERM/SIGHUP/SIGINT and attempts to
gracefully terminate as soon as possible. Allow the user to abort
immediately, by hitting Ctrl-C several times.
Bug-Debian: https://bugs.debian.org/679975
Signed-off-by: Ilias Tsitsimpis <i.tsitsimpis@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This reverts commit a1dc76ae91.
Causes a crash when using Blinkenlights UI with -l CLI option.
$ ./offlineimap.py -c offlineimap.conf.minimal -u blinkenlights -l foo
Traceback (most recent call last):
File "./offlineimap.py", line 36, in <module>
oi.run()
File "/tmp/offlineimap/offlineimap/init.py", line 50, in run
options, args = self.__parse_cmd_options()
File "/tmp/offlineimap/offlineimap/init.py", line 205, in __parse_cmd_options
self.ui.setlogfile(options.logfile)
File "/tmp/offlineimap/offlineimap/ui/UIBase.py", line 119, in setlogfile
self.logger.info(msg)
File "/usr/lib/python2.7/logging/__init__.py", line 1159, in info
self._log(INFO, msg, args, **kwargs)
File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
self.handle(record)
File "/usr/lib/python2.7/logging/__init__.py", line 1288, in handle
self.callHandlers(record)
File "/usr/lib/python2.7/logging/__init__.py", line 1328, in callHandlers
hdlr.handle(record)
File "/usr/lib/python2.7/logging/__init__.py", line 751, in handle
self.emit(record)
File "/tmp/offlineimap/offlineimap/ui/Curses.py", line 305, in emit
color = self.ui.gettf().curses_color
AttributeError: 'CursesLogHandler' object has no attribute 'ui'
Reported-by: iliastsi
Github-issue: #293
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The retry loop would release connection that would get
re-released upon ``finally`` clause. In consequence, an
exception would be cast.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This fix does not apply when any keyword in configured which is already
harmless.
Written-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Extract the flag/keyword translation and combination logic to a
function.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This uses the destination folder's keyword mapping to translate the
message's keywords into some appropriate format.
Tested only with local Maildir.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The keywords are in the flag string, so imaputil can just strip the
usual \Flags.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit assembles a dictionary mapping user-specified IMAP keywords
to Maildir lower-case flags, similar to Dovecot's format
http://wiki2.dovecot.org/MailboxFormat/Maildir
Configuration example:
[Repository Local]
type = Maildir
localfolders = ~/Maildir/
customflag_a = $label1
customflag_b = $Forwarded
customflag_c = Junk
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Remove filtering that was previously done to avoid errors in flag
handling.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Note that the stacks are grouped if similar, and the current
process (the one handling the signal) is identified and reports
where it was before the signal.
This can be quite handy when wanting to debug thread locks for
instance.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
If this value is true, use (if possible) a timestamp based on message
Date or Delivery-date headers. The current system time is used
otherwise.
filename_use_mail_timestamp and utime_from_header are now completely
separated option that do not interfere one with other.
To handle this feature in a multithread context we use a hash to count
the number of mail with the same timestamp. This method is more accurate
than using the old lasttime and timeseq variables.
Signed-off-by: Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Rather than having an option for syslog output, make a separate UI
option.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Handle case where email's internal time is erroneously so large as to
cause overflow errors when setting file modification time with
utime_from_header = true.
Reported-by: Cameron Simpson <cs@zip.com.au>
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Allow the user to block usage of known-bad versions of SSL and TLS.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Return value set to 1 if sync failed and error is thrown. Otherwise set to 0 if successful.
Signed-off-by: Prashant Sachdeva <sachdevp@cs.ubc.ca>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
When new mail arrives, this hook is triggered, allowing the user to
play a sound, or launch a popup.
Signed-off-by: Matthew Krafczyk <krafczyk.matthew@gmail.com>
Since skipping a folder means no new data is downloaded, the UID validity
problem is a backup failure. Make it possible to alert or work around
it in scripts by signaling with the exit code.
Signed-off-by: Alex Kapranoff <alex@kapranoff.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Now it is possible to handle failed syncs in scripts.
Signed-off-by: Alex Kapranoff <alex@kapranoff.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
1. When using maxage, local and remote messagelists are supposed to only
contain messages from at most maxage days ago. But local and remote used
different timezones to calculate what "maxage days ago" means, resulting
in removals on one side. Now, we ask the local folder for maxage days'
worth of mail, find the lowest UID, and then ask the remote folder for
all UID's starting with that lowest one.
2. maxage was fundamentally wrong in the IMAP-IMAP case: it assumed that
remote messages have UIDs in the same order as their local counterparts,
which could be false, e.g. when messages are copied in quick succession.
So, remove support for maxage in the IMAP-IMAP case.
3. Add startdate option for IMAP-IMAP syncs: use messages from the given
repository starting at startdate, and all messages from the other
repository. In the first sync, the other repository must be empty.
4. Allow maxage to be specified either as number of days to sync (as
previously) or as a fixed date.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Previously, syncing labels on a message always resulted in updating the
file modification time, even with utime_from_headers=true
This patch restores the file mtime to the previous value when
utime_from_headers=true, preventing a label synchronization from
breaking the promise that the file mtimes coincide with the header date.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
We were using rtime for two different purposes:
- to store remote internal date
- to use in the utime_from_header option
Let's decouple the utime_from_header logic from rtime, now rtime means
remote internal date.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Upstream bug has been fixed, since imaplib2 v2.42 the untagged responses are
flushed (as stated by the documentation).
See https://sourceforge.net/p/imaplib2/bugs/7/
Signed-off-by: Pierre-Louis Bonicoli <pierre-louis.bonicoli@gmx.fr>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This partially reverts commit 25513e9038.
Only changes about dates and times are reverted. The changes about the style are
kept.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The basic problem is in the context of syncing multiple accounts where
one is fast and the others are slower (due to the number of folders).
When the fast account completes, the other accounts are partially written
through the list and if the file is read during this time, the list can
be useless. However, in the general case, the file is probably left
around from a previous run of offlineimap and is more correct, so add an
option to leave it alone until all syncing is done.
Incremental is still the default since this running offlineimap using
its own timer setup is likely the most common setup. Turning it off
works best with one-shot mode triggered by cron or systemd timers.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Fix regresssion introduced in 428349e3.
Prevent messages with UID's already in the destination folder from getting
excluded from the copy list.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Some messages were excluded from the copy/delete list after the UI message said
they were copied/deleted.
Also fix Internaldate2epoch(), which was wrong.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Suppose messages A and B were delivered to the remote folder at
"maxage + 1" days ago.
A was downloaded to the local folder "maxage + 1" days ago, but B was only
downloaded "maxage - 1" days ago (contrived scenario to illustrate the two
things that could happen). The behavior was that B gets deleted from the local
folder, but A did not. The expected behavior is that neither is deleted.
Starting where Base.py: __syncmessagesto_delete(self, dstfolder, statusfolder)
is called where:
- self is the remote folder
and
- dstfolder is the local folder.
It defines deletelist to be the list of messages in the status folder
messagelist that aren't in the remote folder messagelist with
not self.uidexists(uid)
A and B are both in the status folder. They're also both *NOT* in the remote
folder messagelist: this list is formed in IMAP.py: cachemessagelist(), which
calls _msgs_to_fetch(), which only asks the IMAP server for messages that are
"< maxage" days old.
Back to Base.py __syncmessagesto_delete(), look at the call
folder.deletemessages(deletelist), where folder is the local folder. This ends
up calling Maildir.py deletemessage() for each message on the deletelist. But we
see that this methods returns (instead of deleting anything) if the message is
in the local folder's messagelist. This messagelist was created by Maildir.py's
cachemessagelist(), which calls _scanfolder(), which tries to exclude messages
based on maxage. So at this point, we *WANT* A and B to be excluded -- then they
will be spared from deletion. This maxage check calls _iswithinmaxage(), and
actually does the date comparison based on the time found at the beginning of
the message's filename. These filenames were originally created in Maildir.py's
new_message_filename(), which calls _gettimeseq() to get the current time (i.e.
the time of retrieval).
Upshot: A's filename has an older timestamp than B's filename. A is excluded
from the local folder messagelist in _scanfolder(), hence spared from deletion
in deletemessage(); B is not excluded, and is deleted.
This patch does not address the timezone issue. As for the IMAP/timezone issue,
a similar issue is discussed in the thunderbird bug tracker here:
https://bugzilla.mozilla.org/show_bug.cgi?id=886534
In the end, they're solving a different problem, but they agree that
there is really no reliable way of guessing the IMAP server's internal
timezone.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Read proxy option in imapserver, instantiate a class in imaplibutil
using a self-defined keyword and a socket instance, and use this socket
instance to substitute the default socket instance used in imaplib2.
Signed-off-by: 夏恺(Xia Kai) <xiaket@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Get real tracebacks (at the point that calls Request.abort()
and not from the point that handles collected abort requests)
and pass them to our calling functions to ease debugging
of user problems.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This simplifies logics for the user, especially if he uses both
fingerprint and certificate validation: it is hard to maintain
the compatibility with the prior behaviour and to avoid getting
default CA bundle to be disabled when fingerprint verification
is requested.
See
http://thread.gmane.org/gmane.mail.imap.offlineimap.general/6695
for discussion about this change.
Default CA bundle is requested via 'sslcertfile = OS-DEFAULT'.
I had also enforced all cases where explicitely-requested CA bundles
are non-existent to be hard errors: when users asks us to use CA
bundle (and, thus, certificate validation), but we can't find one,
we must error out rather than happily continue and downgrade to
no validation.
Reported-By: Edd Barrett <edd@theunixzoo.co.uk>
Reviewed-By: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
We have no variable "fullname", it must have been slipped in
unintentionally.
Blame commit:
0f40ca4799 more style consistency
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The note tells people to look at the source of the method, which
spinx.ext.viewcode conveniently links right next to the methods
signature.
Signed-off-by: Wieland Hoffmann <themineo@gmail.com>
We usually mutate some exceptions to OfflineImapError() and it is
a whole lot better if such exception will show up with the original
traceback, so all valid occurrences of such mutations were transformed
to the 3-tuple form of "raise". Had also added coding guidelines
document where this re-raise strategy is documented.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
CustomConfigParser.getlocaleval() loads "pythonfile" at each call.
Besides unnecessary IO, in case that dynamic_folderfilter is true, the
code in "pythonfile" would behave stateless, since it is re-initialized
at each call of getlocaleval(), i.e., at every sync. Fix that by keeping
a singleton copy of localeval in CustomConfigParser after the first call
of getlocaleval().
Signed-off-by: Stefan Huber <shuber@sthu.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Otherwise, messages logged through UIBase.error would only be passed to
UIBase._msg, which only logs at INFO. This causes error to not get
logged at all for the quit UI.
Signed-off-by: Wieland Hoffmann <themineo@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This fixes a bug in which a message ended up with multiple gmail labels
header (X-Keywords or so). Fix fix it by removing all labels headers
before adding the updated one.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
There should be just one header storing gmail labels, but due to a bug,
multiple X-Keywords (or equivalent) headers may be found on the local
messages.
Now we, when extracting the labels from a message, we read all label
headers, instead of just the first one.
This has the consequence that some old labels stored locally in a second
X-Keywords (or third...) header, which effectively was rendered
invisible to offlineimap until now, may pop back up again and be pushed
to gmail. No labels will be removed by the changes in this commit,
though.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
It is a bit cleaner than making chains of calls like
{{{
value = os.path.expanduser(value)
value = os.path.abspath(value)
}}}
since we do see all transformations to be applied in a single
iterable and have no repeated code like in the above example.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
- Multi-line documentation for functions and methods
now has ending triple-double-quotes on an own line,
as per PEP 257.
- Added documentation and comments to almost all functions
and methods.
- Added stub implementations for getconfig() and getsection()
inside CustomConfig.ConfigHelperMixin to provide sane
run-time diagnostics for classes that doesn't implement them.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The GNU GPL and the OpenSSL license are incompatible. Some distributions
take a hardline stance and do not consider OpenSSL to be a systems library
(which would permit the usage/distribution of OpenSSL) when distributing
apps such as OfflineImap from the same repository. In order to solve these
distributions dilemma, we add the OpenSSL exception to our GNU GPL v2+ license.
This allows for unambiguous use/distribution of our GNU GPL'ed application
with a python linking to openssl.
Consent of all contributors has been requested via email by
Sebastian@SSpaeth.de. With very few exceptions of minor contributions (which
might or might not by copyright-worthy) all past contributors have consented
to adding the OpenSSL exception. None of the replying authors has disagreed
with adding the exception.
The corresponding issues at question:
https://github.com/OfflineIMAP/offlineimap/issues/104
Debian bug #747033
We are still missing consent from:
1 Asheesh Laroia
2 Bart Kerkvliet
4 Daniel Burrows
5 David Favro
1 David Logie
1 Eric Dorland
1 Ethan Schoonover
49 Eygene Ryabinkin
1 Loui Chang
1 Luca Capello
1 Michael Witten
2 Mike Dawson
1 Peter Colberg
1 Scott Henson
1 Tom Lawton
1 W. Trevor King
2 X-Ryl669
1 buergi
2 dtk
5 mj
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Commit 7df765cfdb introduced regression:
GmailMaildir caches labels in its own function and it was testing the
presence of the 'labels' key in message descriptor. But 7df765cf
changed descriptor initialization and this key is always present.
So now we have 'labels_cached' flag that tells us if labels were
already cached or not.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Create initializer function that puts default values to all fields
of message list item. Fix all code that directly assigns some hash
to the elements of messagelist: for direct assignments only initializer
is now permitted, all other modification are done in-place.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The example illustrations were slightly cryptic;
modify them to be more obvious.
Fix case #2 (message starts with two line breaks)
where additional line break was shown and coded.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The parameter's value is a string representing the linebreak,
and can sometimes contain just '\n', in which case naming it
crlf is slightly misleading.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
For cases like
http://article.gmane.org/gmane.mail.imap.offlineimap.general/6468
it is beneficial to see that folder name was translated and the result
of this translation on a single line: having log like
{{{
Folder Boring/Wreck [acc: tmarble@info9.net]:
Syncing Boring/Breck: Gmail -> Maildir
}}}
with translated name on the "Folder" line and original one on the
"Syncing" line isn't very intuitive.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
It is always good to see which version we're talking about, so I had
added explicit marker for -devel, -release, -rcX and other states of
the OfflineIMAP.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
For servers without UIDPLUS we are inserting additional header
just after transformation '\n' -> CRLF was done. addmessageheaders()
was written to work with just '\n' as the separator, so X-OfflineIMAP
header wasn't preceeded by the CRLF, but just by '\n'.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
private methods prevent them from being overriden on derived classes. In
GmailFolder we need to override copymessageto, so it can't be private.
Before this commit, copymessageto was made private in Base but not in
GmailFolder. The end result was that labels were not set when copying
the message content, and always needed to be set on the label copying
pass.
Pointyhat-to: Eygene Ryabinkin
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
... and not self.filterheaders. With the current code this change
is no-op (since self.filterheaders is always passed as header_list),
but it is a bug in general.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
If when we request a LocalStatus folder, the folder has to be created,
we look whether the other backend has data, and if it does we migrate
it to the new backend.
The old backend data is left untouched, so that if you change back say
from sqlite to plaintext, the older data is still there. That should
not lead to data loss, only a slower sync while the status folder gets
updated.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
* Do not inherit LocalStatusSQLiteFolder class from the plaintext
one.
* Use some functions already in BaseFolder in both, plaintext and
sqlite classes.
* Add a saveall method. The idea is that saveall dumps the entire
messagelist to disk, while save only commits the uncommited
changes. Right now, save is noop for sqlite, and equivalent to
saveall for plaintext, but it enables to be more clever on when we
commit to disk in the future.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
* Implements Status Folder format v2, with a mechanism to upgrade an
old statusfolder.
* Do not warn about Gmail and GmailMaildir needing sqlite backend
anymore.
* Clean repository.LocalStatus reusing some code from
folder.LocalStatus.
* Change field separator in the plaintext file from ':' to '|'. Now
the local status stores gmail labels. If they contain field
separator character (formerly ':'), they get messed up. The new
character '|' is less likely to appear in a label.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Format headers X-Label and Keywords as a space separated list and all
other ones as comma-separated entities. This makes OfflineIMAP label
handling to be compatible with some user agents that recognise these
headers.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When synclabels config flag is set to "yes" for the GMail repo,
offlineimap fetches the message labels along with the messages, and
embeds them into the body under the header X-Keywords (or whatever
'labelsheader' was set to), as a comma separated list.
It also adds an extra pass to savemessageto, that performs label
synchronization on existing messages from GMail to local, the same way
it is done with flags.
We also introduce GmailMaildir repository that adds functionality to
change message labels. It keeps track of messages modification time,
so one can quickly detect when the labels may have changed.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
In preparation for GMail label sync, we had split our some functionality
that will be needed further into their own functions. This also permitted
the code to look more compact and concise.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When filterheaders is set to a comma-separated list of headers,
OfflineIMAP removes those headers from messages before uploading them
to the server.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Since we just do multiple passes for saving the message without
actually modifying its content (apart from header insertion that
is CRLF-clean), we can change line ends to the proper CRLF just
once.
And we can also get message's date only once too.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Added the configuration setting usecompression for the IMAP repositories.
When enabled, the data from and to the IMAP server is compressed.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Make external API of class/module to be smaller, explicitely mark
all internal functions. Also annotate methods that are implemented
as the part of the parent class interface.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Allow people who want folder filtering to depend on the external
conditions or to make it dynamic for other reasons, to do what
they want.
New repository configuration knob 'dynamic_folderfilter' was
introduced; it defaults to 'False' that matches historical behaviour.
GitHub: #73
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit fixes the case when we're invoking releaseconnection()
for a given imapobj twice.
This bug manifests itself as
{{{
ValueError: list.remove(x): x not in list
File "[...]/offlineimap/folder/IMAP.py", line 615, in savemessage
self.imapserver.releaseconnection(imapobj)
File "[...]/offlineimap/imapserver.py", line 130, in releaseconnection
self.assignedconnections.remove(connection)
}}}
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When imaputil was parsing quoted strings, it treated "abcd\\"
as incomplete quoted string having escaped quote, rather than
properly-quoted string having escaped backslash.
GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/53
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>