mailbox-list-index-backend.c revision bb2471ff14f01390b47cce63b407820b5547df1a
/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "hostpid.h"
#include "mail-index.h"
#include "subscription-file.h"
#include "mailbox-list-delete.h"
#include "mailbox-list-subscriptions.h"
#include "mailbox-list-index-storage.h"
#include "mailbox-list-index-sync.h"
#include <stdio.h>
#define GLOBAL_TEMP_PREFIX ".temp."
struct index_mailbox_list {
struct mailbox_list list;
const char *temp_prefix;
const char *create_mailbox_name;
};
extern struct mailbox_list index_mailbox_list;
static struct mailbox_list *index_list_alloc(void)
{
struct index_mailbox_list *list;
}
{
const char *dir;
*error_r = "LAYOUT=index requires mailbox_list_index=yes";
return -1;
}
return -1;
}
return 0;
}
{
}
{
}
static int
struct mail_index_view *view,
const char *name,
struct mailbox_list_index_node **node_r,
{
unsigned int i;
*seq_r = 0;
for (i = 0; i < 2; i++) {
return 0;
return 1;
/* mailbox was just expunged. refreshing should notice it. */
return -1;
}
i_panic("mailbox list index: refreshing doesn't lose expunged uid=%u",
return -1;
}
static const char *
const guid_128_t mailbox_guid)
{
}
static int
{
struct mail_index_view *view;
struct mailbox_list_index_node *node;
struct mailbox_status status;
const char *root_dir;
int ret;
/* return root directories */
path_r) ? 1 : 0;
}
/* consistently use mailbox_dir_name as part of all mailbox
switch (type) {
break;
break;
default:
break;
}
return 0;
return 1;
}
/* we could get here during sync from
index_list_mailbox_create_selectable() */
seq = 0;
ret = 0;
ret = 1;
} else {
}
} else {
return -1;
if (ret < 0) {
return -1;
}
}
if (ret == 0) {
ret = -1;
&status, mailbox_guid) ||
ret = -1;
} else {
ret = 1;
}
return ret;
}
static const char *
{
}
{
const char *path;
"Subscriptions not supported");
return -1;
}
}
static int
enum mailbox_existence *existence_r)
{
struct mailbox_list_index_node *node;
return -1;
return 0;
MAILBOX_LIST_INDEX_FLAG_NOSELECT)) == 0) {
/* selectable */
} else {
/* non-selectable */
}
return 0;
}
static int
{
struct mailbox_list_index_sync_context *sync_ctx;
struct mailbox_list_index_node *node;
bool created;
int ret;
return -1;
/* didn't already exist */
ret = 1;
} else {
/* already existed */
ret = 0;
}
ret = -1;
return ret;
}
static int
const guid_128_t mailbox_guid)
{
struct index_mailbox_list *list =
struct mailbox_list_index_sync_context *sync_ctx;
struct mailbox_list_index_record rec;
struct mailbox_list_index_node *node;
const void *data;
return -1;
if (!created &&
MAILBOX_LIST_INDEX_FLAG_NOSELECT)) == 0) {
/* already selectable */
return 0;
}
/* make it selectable */
/* make sure we forget any changes done internally */
return -1;
}
return 1;
}
static int
{
struct index_mailbox_list *list =
struct mailbox_update new_update;
enum mailbox_existence existence;
int ret;
/* first do a quick check that it doesn't exist */
return -1;
}
/* now add the directory to index locked */
return -1;
}
/* if no GUID is requested, generate it ourself. set
UIDVALIDITY to index sometimes later. */
else
new_update = *update;
/* create the backend mailbox first before it exists in the
list. the mailbox creation wants to use get_path() though,
so use a bit kludgy create_mailbox_* variables during the
creation to return the path. we'll also support recursively
creating more mailboxes in here. */
const char *old_name;
if (ret == 0) {
/* backend mailbox was successfully created. now add it
to the list. */
if (ret < 0)
if (ret <= 0) {
/* failed to add to list. rollback the backend
mailbox creation */
(void)mailbox_delete(box);
}
}
if (ret < 0)
return ret;
} else {
ret = 0;
}
if (ret == 0) {
"Mailbox already exists");
return -1;
}
return 0;
}
static int
const struct mailbox_update *update)
{
&old_path) <= 0)
return -1;
/* rename the directory */
&root_dir)) {
;
;
return -1;
} else {
"rename(%s, %s) failed: %m",
return -1;
}
}
return 0;
}
static int
enum mailbox_existence *existence_r)
{
struct index_mailbox_list *list =
return -1;
}
return 0;
}
static void
enum mailbox_list_path_type type)
{
const char *mailbox_path, *path;
&mailbox_path) <= 0 ||
return;
/* this directory may contain also child mailboxes' data.
we don't want to delete that. */
rmdir_path) < 0)
return;
} else {
if (mailbox_list_delete_trash(path) < 0 &&
"unlink_directory(%s) failed: %m", path);
}
}
/* avoid leaving empty directories lying around */
}
static void
{
}
static int
bool delete_selectable)
{
struct mailbox_list_index_sync_context *sync_ctx;
int ret;
/* we're rollbacking a failed create. if the name exists in the
list, it was done by somebody else so we don't want to
remove it. */
return 0;
}
return -1;
return -1;
return ret;
}
static int
{
const char *path;
int ret;
/* first delete the mailbox files */
&path);
if (ret <= 0)
return ret;
ret = 0;
} else {
}
if (ret == 0) {
return -1;
}
return ret;
}
static int
{
int ret;
return -1;
if (ret == 0) {
"Mailbox has children, delete them first");
return -1;
}
return 0;
}
static int
const char *name ATTR_UNUSED)
{
"Symlinks not supported");
return -1;
}
static int
{
struct mailbox_list_index_sync_context *sync_ctx;
const void *data;
"Renaming not supported across namespaces.");
return -1;
}
return -1;
return -1;
}
if (!created) {
"Target mailbox already exists");
return -1;
}
/* copy all the data from old node to new node */
/* remove the old node from existence */
/* update the old index record to contain the new name_id/parent_uid,
then expunge the added index record */
}
static struct mailbox_list_iterate_context *
const char *const *patterns,
enum mailbox_list_iter_flags flags)
{
struct mailbox_list_iterate_context *ctx;
if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
flags);
}
return ctx;
}
static const struct mailbox_info *
{
return mailbox_list_subscriptions_iter_next(ctx);
return NULL;
}
{
return 0;
}
struct mailbox_list index_mailbox_list = {
{
NULL,
NULL,
NULL,
NULL,
}
};
{
return;
}