virtual-storage.c revision 814bf67459ad405a157af0b8940602024d7fadfe
/* Copyright (c) 2008-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "str.h"
#include "llist.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "index-mail.h"
#include "mail-copy.h"
#include "mail-search.h"
#include "mailbox-list-private.h"
#include "virtual-plugin.h"
#include "virtual-transaction.h"
#include "virtual-storage.h"
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#define VIRTUAL_DEFAULT_MAX_OPEN_MAILBOXES 64
extern struct mail_storage virtual_storage;
extern struct mailbox virtual_mailbox;
extern struct virtual_mailbox_vfuncs virtual_mailbox_vfuncs;
{
}
{
else {
return t_strdup_printf("<hidden>%c%s",
}
}
{
enum mail_error error;
}
static struct mail_storage *virtual_storage_alloc(void)
{
struct virtual_storage *storage;
}
static int
const char **error_r)
{
const char *value;
*error_r = "Invalid virtual_max_open_mailboxes setting";
return -1;
}
return 0;
}
static void
struct mailbox_list_settings *set)
{
}
struct virtual_backend_box *
{
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
for (i = 0; i < count; i++) {
return bboxes[i];
}
return NULL;
}
struct virtual_backend_box *
{
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
if (mailbox_id == 0)
return NULL;
for (i = 0; i < count; i++) {
return bboxes[i];
}
return NULL;
}
const char *name)
{
const char *const *names;
unsigned int i, count;
for (i = 0; i < count; i++) {
return TRUE;
}
return FALSE;
}
struct virtual_backend_box *bbox)
{
enum mail_error error;
const char *str;
"Virtual mailbox open failed because of mailbox %s: %s",
/* this mailbox wasn't explicitly specified. just skip it. */
return 0;
}
return -1;
}
struct virtual_backend_box *bbox,
enum mailbox_flags flags)
{
struct mail_namespace *ns;
const char *mailbox;
enum mailbox_existence existence;
if (!bbox->clear_recent)
if (existence != MAILBOX_EXISTENCE_SELECT) {
/* ignore this. it could be intentional. */
i_debug("virtual mailbox %s: "
"Skipping non-existing mailbox %s",
}
return 0;
}
/* we use modseqs for being able to check quickly if backend mailboxes
have changed. make sure the backend has them enabled. */
return 1;
}
enum mailbox_flags flags)
{
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
int ret;
for (i = 0; i < count; ) {
if (ret <= 0) {
if (ret < 0)
break;
} else {
i++;
}
}
if (i == count)
return 0;
else {
/* failed */
for (; i > 0; i--) {
}
return -1;
}
}
static struct mailbox *
{
struct virtual_mailbox *mbox;
}
{
struct mailbox_transaction_context *trans;
(void)mailbox_transaction_commit(&trans);
}
}
{
/* FIXME: IMAP IDLE running - we should support closing this
also if mailbox_list_index=yes */
return FALSE;
}
/* FIXME: we could probably close this by making
syncing support it? */
return FALSE;
}
return TRUE;
}
static bool
struct virtual_backend_box *except_bbox)
{
struct virtual_backend_box *bbox;
/* first try to close a mailbox without any transactions.
we'll also skip any mailbox that has notifications enabled (ideally
these would be handled by mailbox list index) */
if (bbox != except_bbox &&
return TRUE;
}
}
/* next try to close a mailbox that has sync_mail, but no
other transactions */
if (bbox != except_bbox &&
return TRUE;
}
}
return FALSE;
}
struct virtual_backend_box *bbox)
{
/* the backend mailbox was already opened. if we didn't get here
from virtual_backend_box_open() we may need to close a mailbox */
;
}
struct virtual_backend_box *bbox)
{
/* try to keep the number of open mailboxes below the threshold
before opening the mailbox */
;
return -1;
return 0;
}
struct virtual_backend_box *bbox)
{
}
}
struct virtual_backend_box *bbox)
{
}
{
struct virtual_backend_box **bboxes;
unsigned int i, count;
for (i = 0; i < count; i++) {
continue;
}
}
static int
enum mailbox_existence *existence_r)
{
}
{
bool broken;
int ret = 0;
return -1;
}
if (ret == 0) {
}
if (ret < 0) {
return -1;
}
return -1;
sizeof(struct virtual_mail_index_record),
sizeof(uint32_t));
return -1;
}
return 0;
}
{
}
{
}
static int
bool directory ATTR_UNUSED)
{
"Can't create virtual mailboxes");
return -1;
}
static int
{
"Can't update virtual mailboxes");
return -1;
}
{
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
struct mailbox_status status;
bool opened;
for (i = 0; i < count; i++) {
return -1;
}
if (!status.have_guids)
if (!status.have_save_guids)
}
return 0;
}
static int
enum mailbox_status_items items,
struct mailbox_status *status_r)
{
if ((items & STATUS_LAST_CACHED_SEQ) != 0)
items |= STATUS_MESSAGES;
return -1;
if ((items & STATUS_LAST_CACHED_SEQ) != 0) {
/* Virtual mailboxes have no cached data of their own, so the
current value is always 0. The most important use for this
functionality is for "doveadm index" to do FTS indexing and
it doesn't really matter there if we set this value
correctly or not. So for now just assume that everything is
indexed. */
}
if (!mbox->have_guid_flags_set) {
if (virtual_storage_set_have_guid_flags(mbox) < 0)
return -1;
}
if (mbox->have_guids)
if (mbox->have_save_guids)
return 0;
}
static int
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r)
{
return -1;
if ((items & MAILBOX_METADATA_GUID) != 0) {
"Virtual mailboxes have no GUIDs");
return -1;
}
return 0;
}
static void
{
}
{
struct virtual_backend_box *const *bboxp;
return;
}
/* FIXME: if mailbox_list_index=yes, use mailbox-list-notify.h API
to wait for changes and avoid opening all mailboxes here. */
/* we can't report error in here, so do it later */
continue;
}
}
}
static void
struct mailbox *backend_mailbox,
{
struct virtual_backend_box *bbox;
const struct virtual_backend_uidmap *uids;
struct seq_range_iter iter;
unsigned int n, i, count;
else {
}
return;
uids[i].virtual_uid);
i++;
}
}
}
static void
struct mailbox *backend_mailbox,
{
struct virtual_backend_box *bbox;
const struct virtual_backend_uidmap *uids;
struct seq_range_iter iter;
unsigned int n, i, count;
else {
}
return;
} else {
i++;
}
}
}
static void
bool only_with_msgs)
{
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
for (i = 0; i < count; i++) {
}
}
{
if (mbox->inconsistent)
return TRUE;
return index_storage_is_inconsistent(box);
}
static int
{
/* we don't have any quick and easy optimizations for tracking
virtual folders. ideally we'd completely disable mailbox list
indexes for them, but this is the easiest way to do it for now. */
return 1;
}
static void
{
}
struct mail_storage virtual_storage = {
.v = {
NULL,
NULL,
NULL,
}
};
struct mailbox virtual_mailbox = {
.v = {
NULL,
NULL,
NULL,
NULL,
NULL,
}
};
struct virtual_mailbox_vfuncs virtual_mailbox_vfuncs = {
};