mailbox-list-index.c revision 2454dfa32c93c20a8522c6ed42fe057baaac9f9a
/* Copyright (c) 2006-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "hash.h"
#include "str.h"
#include "mail-index-view-private.h"
#include "mail-storage-hooks.h"
#include "mail-storage-private.h"
#include "mailbox-list-index-storage.h"
#include "mailbox-list-index-sync.h"
#define MAILBOX_LIST_INDEX_REFRESH_DELAY_MSECS 1000
/* dovecot.list.index.log doesn't have to be kept for that long. */
{
}
{
}
{
ilist->highest_name_id = 0;
ilist->sync_log_file_seq = 0;
ilist->sync_log_file_offset = 0;
}
{
struct mailbox_permissions perm;
unsigned int lock_timeout;
return 0;
if (mailbox_list_mkdir_missing_index_root(list) < 0)
return -1;
/* LAYOUT=index. this is the only location for the mailbox
data, so we must never move it into memory. */
}
/* try opening once more. it should be created
directly into memory now, except if it fails with
LAYOUT=index backend. */
index_flags) < 0) {
return -1;
}
}
}
return 0;
}
struct mailbox_list_index_node *
const char *name)
{
return node;
}
return NULL;
}
static struct mailbox_list_index_node *
{
const char *const *path;
unsigned int i;
char sep[2];
if (*name == '\0')
for (i = 0;; i++) {
break;
}
return node;
}
struct mailbox_list_index_node *
{
struct mailbox_list_index_node *node;
T_BEGIN {
} T_END;
return node;
}
struct mailbox_list_index_node *
{
}
{
}
}
struct mailbox_list_index_node *node)
{
struct mailbox_list_index_node **prev;
}
struct mail_index_view *view)
{
const void *data, *name_start, *p;
char *name;
int ret = 0;
if (size == 0)
return 0;
for (i = sizeof(struct mailbox_list_index_header); i < size; ) {
/* get id */
return -1;
i += sizeof(id);
/* allow extra space in the end as long as last id=0 */
return id == 0 ? 0 : -1;
}
/* get name */
if (p == NULL)
return -1;
len = (const char *)p - (const char *)name_start;
} else {
/* corrupted index. fix the name. */
str_truncate(str, 0);
ret = -1;
}
i += len + 1;
/* add id => name to hash table */
}
return ret;
}
static void
struct mailbox_list_index_node *node)
{
char *name;
}
const struct mailbox_list_index_node *n2)
{
}
static unsigned int
{
}
const struct mailbox_list_index_node *node)
{
const struct mailbox_list_index_node *n;
if (n == node)
return TRUE;
}
return FALSE;
}
struct mail_index_view *view,
const char **error_r)
{
HASH_TABLE(struct mailbox_list_index_node *,
struct mailbox_list_index_node *) duplicate_hash;
const struct mail_index_record *rec;
const struct mailbox_list_index_record *irec;
const void *data;
bool expunged;
struct mailbox_list_index_node, 1);
*error_r = "Missing list extension data";
/* list index is missing, no point trying
to do second scan either */
count = 0;
break;
}
if (ilist->has_backing_store)
break;
/* generate a new name and use it */
}
}
/* do a second scan to create the actual mailbox tree hierarchy.
this is needed because the parent_uid may be smaller or higher than
the current node's uid */
count = 0;
if (irec->parent_uid != 0) {
/* node should have a parent */
irec->parent_uid);
"parent_uid=%u points to nonexistent record",
irec->parent_uid);
if (ilist->has_backing_store)
break;
/* just place it under the root */
"parent_uid=%u loops to node itself (%s)",
if (ilist->has_backing_store)
break;
/* just place it under the root */
} else {
continue;
}
}
else {
if (ilist->has_backing_store) {
"Duplicate mailbox '%s' in index",
break;
}
/* we have only the mailbox list index and this node
may have a different GUID, so rename it. */
"Duplicate mailbox '%s' in index, renaming to %s",
}
}
}
{
const struct mail_index_header *hdr;
const char *error;
if (!force &&
/* nothing changed */
return 0;
}
if (ilist->has_backing_store) {
return -1;
}
}
"Corrupted mailbox list index %s: %s",
if (ilist->has_backing_store) {
return -1;
}
/* FIXME: find any missing mailboxes, add them and write the
index back. */
}
return 0;
}
struct mail_index_view *view)
{
const struct mailbox_list_index_header *hdr;
const void *data;
if (!ilist->has_backing_store)
return FALSE;
}
{
return 0;
/* we haven't been to ioloop since last refresh, skip checking
it. when we're accessing many mailboxes at once (e.g.
index every single time. */
return 0;
}
return mailbox_list_index_refresh_force(list);
}
{
struct mail_index_view *view;
int ret;
if (mailbox_list_index_index_open(list) < 0)
return -1;
return -1;
}
/* refresh list of mailboxes */
} else {
}
if (mailbox_list_index_handle_corruption(list) < 0)
ret = -1;
return ret;
}
{
(void)mailbox_list_index_refresh(list);
}
{
struct mailbox_list_index_header new_hdr;
struct mail_index_view *view;
struct mail_index_transaction *trans;
sizeof(ilist->last_refresh_timeval));
if (!ilist->has_backing_store)
return;
(void)mailbox_list_index_index_open(list);
if (mail_index_transaction_commit(&trans) < 0)
}
ilist->to_refresh =
}
}
{
struct mail_storage *const *storagep;
int ret = 0;
if (!ilist->call_corruption_callback)
return 0;
/* make sure we don't recurse */
if (ilist->handling_corruption)
return 0;
ret = -1;
else {
/* FIXME: implement a generic handler that
just lists mailbox directories in filesystem
and adds the missing ones to the index. */
}
}
}
if (ret == 0)
return ret;
}
{
struct mailbox_list_index_sync_context *sync_ctx;
return -1;
}
{
}
}
static int
const struct mailbox_update *update,
bool directory)
{
return -1;
return 0;
}
static int
const struct mailbox_update *update)
{
return -1;
return 0;
}
static int
{
}
static int
{
}
static int
const char *oldname,
struct mailbox_list *newlist,
const char *newname)
{
}
static int
{
struct mail_index_view *view;
struct mail_index_transaction *trans;
const void *data;
return -1;
is to trigger NOTIFY watcher to handle SubscriptionChange events */
if (mailbox_list_index_index_open(_list) < 0)
return -1;
else {
}
(void)mail_index_transaction_commit(&trans);
return 0;
}
{
struct mailbox_list_index *ilist;
bool has_backing_store;
/* layout=index doesn't have any backing store */
/* reserve the module context anyway, so syncing code knows
that the index is disabled */
return;
}
/* secondary lists aren't accessible via namespaces, so we
need to finish them now. */
}
}
{
const char *dir;
return;
/* we've delayed this part of the initialization so that mbox format
can override the index root directory path */
&dir)) {
/* in-memory indexes */
}
sizeof(struct mailbox_list_index_header),
sizeof(struct mailbox_list_index_record),
sizeof(uint32_t));
sizeof(uint32_t), 0,
sizeof(uint32_t));
}
static void
{
struct mail_namespace *ns;
}
{
struct index_list_mailbox *ibox;
return;
/* for layout=index these get overridden */
}
static struct mail_storage_hooks mailbox_list_index_hooks = {
};
void mailbox_list_index_init(void); /* called in mailbox-list-register.c */
void mailbox_list_index_init(void)
{
}