mailbox-list-index-backend.c revision d71d05cf4417eaedb4d72491480a7d2bb46d8df3
/* Copyright (c) 2013 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;
};
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;
}
{
}
{
return MAILBOX_LIST_INDEX_HIERARHCY_SEP;
}
static int
struct mailbox_list_index_node **node_r)
{
struct mailbox_list_index_node *node;
return -1;
return 0;
return 1;
}
static const char *
const guid_128_t mailbox_guid)
{
} else {
}
}
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;
if (ret == 0) {
}
return -1;
}
&status, mailbox_guid) ||
ret = -1;
} else {
ret = 1;
}
return ret;
}
static const char *
{
}
{
const char *path;
}
static int
enum mailbox_existence *existence_r)
{
struct mailbox_list_index_node *node;
int ret;
return -1;
if (ret == 0)
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
{
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 */
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;
if (ret < 0) {
return -1;
}
/* the storage backend needs to use the same GUID */
update = &new_update;
} else {
ret = 0;
}
if (ret == 0) {
"Mailbox already exists");
return -1;
}
return directory ? 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;
struct mailbox_list_index_record rec;
struct mailbox_list_index_node *node;
const void *data;
bool expunged;
int ret;
return -1;
return -1;
}
if (ret == 0) {
return -1;
}
if (delete_selectable) {
/* make it at least non-selectable */
rec.uid_validity = 0;
}
/* can't delete this directory before its children,
but we may have made it non-selectable already */
return -1;
return 0;
}
/* we can remove the entire node */
return -1;
return 1;
}
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;
int ret;
"Renaming not supported across namespaces.");
return -1;
}
return -1;
return -1;
}
if (ret == 0) {
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 ATTR_UNUSED,
enum mailbox_list_iter_flags flags)
{
struct mailbox_list_iterate_context *ctx;
return ctx;
}
static const struct mailbox_info *
{
return NULL;
}
{
return 0;
}
struct mailbox_list index_mailbox_list = {
{
NULL,
NULL,
NULL,
NULL,
}
};
{
return;
}