mailbox-list.c revision 266697d2af982a9e52573404a1dd9cf0898bf43c
/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "home-expand.h"
#include "unlink-directory.h"
#include "imap-match.h"
#include "mailbox-tree.h"
#include "mailbox-list-private.h"
#include <time.h>
#include <unistd.h>
#include <dirent.h>
/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
then start renaming them to larger names from end to beginning, which
eventually would start causing the failures when trying to use too
long mailbox names. */
#define MAILBOX_MAX_HIERARCHY_LEVELS 20
#define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 200
/* Message to show to users when critical error occurs */
#define CRITICAL_MSG \
"Internal error occurred. Refer to server log for more information."
struct mailbox_list_module_register mailbox_list_module_register = { 0 };
void mailbox_lists_init(void)
{
}
void mailbox_lists_deinit(void)
{
}
{
const struct mailbox_list *const *drivers;
unsigned int i, count;
for (i = 0; i < count; i++) {
*idx_r = i;
return TRUE;
}
}
return FALSE;
}
{
unsigned int idx;
i_fatal("mailbox_list_register(%s): duplicate driver",
}
}
{
unsigned int idx;
i_fatal("mailbox_list_unregister(%s): unknown driver",
}
}
const char **error_r)
{
const struct mailbox_list *const *class_p;
struct mailbox_list *list;
unsigned int idx;
driver);
return -1;
}
return 0;
}
{
return home_expand(path);
}
int mailbox_list_settings_parse(const char *data,
struct mailbox_list_settings *set,
const char **error_r)
{
/* <root dir> */
tmp++;
value = "";
} else {
value++;
}
else {
return -1;
}
}
return 0;
}
const struct mailbox_list_settings *set,
enum mailbox_list_flags flags)
{
/* copy settings */
if ((flags & MAILBOX_LIST_FLAG_DEBUG) != 0) {
i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
}
if (hook_mailbox_list_created != NULL)
}
{
}
{
}
{
return list->hierarchy_sep;
}
{
}
{
}
{
const char *path;
return;
}
path);
}
/* return safe defaults */
*mode_r = 0600;
return;
}
/* directory's GID is used automatically for new files */
/* group doesn't have any permissions, so don't bother
changing it */
/* using our own gid, no need to change it */
} else {
}
}
const char *pattern)
{
}
const char *name)
{
}
const char *name)
{
}
enum mailbox_list_path_type type)
{
}
{
}
{
}
{
/* the default implementation: */
if (*ref != '\0') {
/* merge reference and pattern */
}
return pattern;
}
const char *name,
enum mailbox_name_status *status)
{
return 0;
}
}
struct mailbox_list_iterate_context *
enum mailbox_list_iter_flags flags)
{
const char *patterns[2];
}
struct mailbox_list_iterate_context *
const char *const *patterns,
enum mailbox_list_iter_flags flags)
{
}
const struct mailbox_info *
{
}
{
}
{
}
{
"Invalid mailbox name");
return -1;
}
"INBOX can't be deleted.");
return -1;
}
}
{
"Invalid mailbox name");
return -1;
}
}
{
return 0;
/* We're most likely using NFS and we can't delete
.nfs* files. */
"Mailbox is still open in another session, "
"can't delete it.");
} else {
"unlink_directory(%s) failed: %m", dir);
}
return -1;
}
const char *name)
{
/* delete the index directory first, so that if we crash we don't
leave indexes for deleted mailboxes lying around */
return -1;
}
/* control directory next */
return -1;
}
return 0;
}
{
/* If we happened to create any of the parents, we need to mark them
nonexistent. */
}
}
static void
struct mailbox_tree_context *tree_ctx,
bool match_parents, const char *name)
{
struct mailbox_node *node;
enum imap_match_result match;
const char *p;
bool created, add_matched;
create_flags = (update_only ||
(MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN) : 0;
add_matched = TRUE;
for (;;) {
if (match == IMAP_MATCH_YES) {
node = update_only ?
if (created) {
if (create_flags != 0)
}
if (!update_only && add_matched)
}
/* We don't want to show the parent mailboxes unless
something else matches them, but if they are matched
we want to show them having child subscriptions */
add_matched = FALSE;
} else {
if ((match & IMAP_MATCH_PARENT) == 0)
break;
/* We've a (possibly) non-subscribed parent mailbox
which has a subscribed child mailbox. Make sure we
return the parent mailbox. */
}
if (!match_parents)
break;
/* see if parent matches */
if (p == NULL)
break;
}
}
struct mailbox_tree_context *tree_ctx,
bool match_parents, const char *name)
{
T_BEGIN {
} T_END;
}
{
return TRUE;
levels++;
level_len = 0;
} else {
level_len++;
}
}
return TRUE;
return TRUE;
return FALSE;
}
{
enum mailbox_list_file_type type;
#ifdef HAVE_DIRENT_D_TYPE
switch (d->d_type) {
case DT_UNKNOWN:
break;
case DT_REG:
break;
case DT_DIR:
break;
case DT_LNK:
break;
default:
break;
}
#else
#endif
return type;
}
enum mail_error *error_r)
{
"Unknown internal list error";
}
{
}
{
}
{
char str[256];
list->error_string =
}
{
/* critical errors may contain sensitive data, so let user
see only "Internal error" with a timestamp to make it
easier to look from log files the actual error message. */
}
{
const char *error_string;
enum mail_error error;
return FALSE;
return TRUE;
}