Also add index_mailbox_update_last_temp_file_scan() for easily updating it.
This is reusing an old "sync timestamp" field. Because it was a timestamp,
it doesn't matter if the old data still exists in it. This field could have
been added as an extension, but that's more work and this feature is generic
enough that it should be useful for many of the mail storage backends.
Timo Sirainen [Mon, 26 Jun 2017 16:30:11 +0000 (19:30 +0300)]
lib-storage: Check for storage existence from index dir with ITERINDEX
The root path creation doesn't really even seem to be necessary, because any
mailbox access will automatically mkdir the missing directories anyway.
Although writing other files might not work so well, such as
mail_attribute_dict that points inside the mail directory.
This change simply changes the mailboxes/ directory to be looked up from
index directory instead of the mail root directory. It also mkdirs the
index/mailboxes/ directory afterwards if it didn't exist. So practically
this change shouldn't break anything, since the mailboxes/ directory should
always exist for both root and the indexes.
Timo Sirainen [Mon, 26 Jun 2017 17:10:17 +0000 (20:10 +0300)]
lib-storage: Add mail_location=..:ITERINDEX
This changes mailbox list iteration to work using INDEX directory instead of
the normal mail directory. This can be helpful when the indexes are stored
on a faster storage.
Timo Sirainen [Fri, 30 Jun 2017 10:56:54 +0000 (13:56 +0300)]
lib-storage: Fix mailbox delete to not delete childrens' INDEX or CONTROL dirs
If mail_location had separate INDEX and/or CONTROL set, deleting a mailbox
with children caused the childrens' index and/or control directories to be
deleted (but the mail/ALT directories weren't).
I'm not sure why the _FLAG_MAILBOX_FILES was treated as a special case
earlier. It shouldn't make a difference.
It should return error on unexpected readdir(), closedir() and unlink()
failures. Also fix handling a race condition with another process deleting
the mailbox at the same time.
Timo Sirainen [Tue, 27 Jun 2017 13:37:16 +0000 (16:37 +0300)]
lib-storage: Use mailbox_list_delete_finish_ret() for fs & maildir++ layout
Fixes a problem where e.g. index directory existed but mail root didn't,
and the mailbox couldn't be fully deleted. This was especially a problem
with ITERINDEX enabled.
It means that the user's home directory doesn't exist, which is pretty
unexpected. Home directory is supposed to be created when the storage is
initialized.
Stephan Bosch [Fri, 20 Jan 2017 00:10:04 +0000 (01:10 +0100)]
lib-http: client: Drop peer immediately if it has no more linked queues and it is not connected and not waiting for a backoff timeout.
It is currently unlikely to happen at this point, but it is better to make sure it is handled appropriately.
The pending shared HTTP client changes will make this a likely event.
This surfaced as a problem for the HTTP proxy.
Timo Sirainen [Mon, 19 Jun 2017 08:30:27 +0000 (11:30 +0300)]
acl: Add acl_globals_only setting
The local dovecot-acl files aren't even attempted to be looked up if this is
set. This is mainly useful to avoid unnecessary stat()s to dovecot-acl files
that never exist.
Timo Sirainen [Sun, 18 Jun 2017 08:14:05 +0000 (11:14 +0300)]
imap: NOTIFY - Fix crash due to not hooking into commands correctly
The pre/post hooks aren't always called immediately when commands are
created. They're called only after the command input is being read.
Call notify hooks explicitly now immediately when commands are allocated.
Fixes a panic with for example:
a notify set (selected (Messagenew (uid flags) MessageExpunge FlagChange) personal (MessageNew MessageExpunge FlagChange))
b select inbox
c store 1 +flags \deleted
d expunge
e append inbox {10}
Which crashed with:
Panic: file imap-notify.c: line 397 (imap_notify_callback): assertion failed: (client->command_queue_size == 0)
Stephan Bosch [Thu, 15 Jun 2017 07:18:03 +0000 (09:18 +0200)]
lib: Fix ostream-buffer to return buffer contents size in o_stream_get_buffer_used_size().
This is necessary for querying o_stream_get_buffer_avail_size() with respect to a limit set earlier using o_stream_set_max_buffer_size().
This is mainly useful for test suites.
Timo Sirainen [Mon, 12 Jun 2017 21:57:08 +0000 (00:57 +0300)]
imapc: Fix prefetching specific headers
FETCH BODY[HEADER.FIELDS ...] shouldn't be used if imapc_features doesn't
include fetch-headers. Also neither this nor BODY[HEADER] should be sent
if we already have header/body stream.
Timo Sirainen [Tue, 13 Jun 2017 19:14:11 +0000 (22:14 +0300)]
lib-index: Fix cache lookups from uncommitted transactions with in-memory indexes
This especially fixes mail_get_header_stream() with imapc and
imapc_features=fetch-headers, because it works by first fetching the
specific headers and putting them to the cache transaction, then later on
relying on index_mail_get_header_stream() to get them from the transaction.
Before this fix they wouldn't be found, which triggered another unnecessary
FETCH BODY.PEEK[HEADER].
Timo Sirainen [Mon, 12 Jun 2017 19:52:56 +0000 (22:52 +0300)]
*-login: Add client_vfuncs.input_next_cmd()
This allows plugins to hook into all the pre-login commands. For example
with imap-login most of the commands could already be hooked into, except
for ID and AUTHENTICATE because their parameters reading is handled
specially. This allows hooking into them as well.
This is actually internal to all the login binaries, so it wouldn't have to
be in login-common. However, login-common already has all the code to handle
overriding functions nicely and this is a rather useful feature for all the
protocols anyway, so it's easier this way and not too ugly.
Timo Sirainen [Mon, 12 Jun 2017 20:45:05 +0000 (23:45 +0300)]
push-notification: Switch to main ioloop while calling drivers' commit callbacks
There aren't any guarantees what ioloop happens to be active at the time
the commit is called. The active ioloop can also be destroyed early on,
which can cause an I/O leak and crashes later on.
Some consumers of lib.h are in C++ and therefore they try to compile
byteorder.h as C++ code. C++ compilers don't like the implicit void *
-> struct anything * conversion, so we squelch those by adding explicit
casts.