index-storage.c revision c0bfb67ba32064347bac3241f1aac9b8a809e2f1
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "istream.h"
#include "ioloop.h"
#include "imap-parser.h"
#include "mkdir-parents.h"
#include "mail-index-private.h"
#include "mail-index-modseq.h"
#include "mailbox-list-private.h"
#include "index-storage.h"
#include "index-mail.h"
#include "index-thread-private.h"
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
/* How many seconds to keep index opened for reuse after it's been closed */
#define INDEX_CACHE_TIMEOUT 10
/* How many closed indexes to keep */
#define INDEX_CACHE_MAX 3
#define LOCK_NOTIFY_INTERVAL 30
struct index_list {
struct index_list *next;
struct mail_index *index;
char *mailbox_path;
int refcount;
};
static struct index_list *
{
struct index_list *list;
return list;
}
{
}
{
int n = 0;
return 0;
break;
"mkdir(%s) failed: %m", index_dir);
return -1;
}
/* create the parent directory first */
&parent_mode, &parent_gid);
"mkdir(%s) failed: %m", parent_dir);
return -1;
}
}
return 0;
}
static const char *
{
const char *index_dir;
if (*index_dir == '\0') {
/* disabled */
return NULL;
}
/* it'll be created later */
return index_dir;
}
return NULL;
}
return NULL;
}
return index_dir;
}
static struct mail_index *
{
const char *index_dir, *mailbox_path;
int destroy_count;
/* compare index_dir inodes so we don't break even with symlinks.
if index_dir doesn't exist yet or if using in-memory indexes, just
compare mailbox paths */
/* already found the index. we're just going through
the rest of them to drop 0 refcounts */
/* make sure the directory still exists.
it might have been renamed and we're trying
to access it via its new path now. */
rec->destroy_time = 0;
else
}
} else {
}
destroy_count >= INDEX_CACHE_MAX) {
continue;
} else {
}
}
}
mailbox_path, &st);
} else {
}
}
static void destroy_unrefed(bool all)
{
} else {
}
}
}
{
}
{
struct index_list *list;
break;
}
}
}
void index_storage_destroy_unrefed(void)
{
}
{
}
enum mail_cache_decision_type dec)
{
const char *const *arr;
int i;
return;
for (i = 0; i < MAIL_INDEX_CACHE_FIELD_COUNT; i++) {
*arr) == 0) {
break;
}
}
if (i == MAIL_INDEX_CACHE_FIELD_COUNT) {
i_error("%s: Invalid cache field name '%s', ignoring ",
}
}
}
{
static bool initialized = FALSE;
if (!initialized) {
initialized = TRUE;
set_cache_decisions("mail_cache_fields",
set_cache_decisions("mail_never_cache_fields",
}
sizeof(global_cache_fields));
}
unsigned int secs_left)
{
const char *str;
/* if notify type changes, print the message immediately */
/* first override notification, show it */
} else {
return;
}
}
switch (notify_type) {
case MAILBOX_LOCK_NOTIFY_NONE:
break;
break;
"%u seconds", secs_left);
break;
break;
"will override in %u seconds", secs_left);
break;
}
}
{
}
{
enum file_lock_method lock_method =
const char *index_dir;
int ret;
if (box->file_create_mode == 0) {
&box->file_create_gid);
&dir_gid);
}
if (!ibox->move_to_memory)
if (ibox->keep_index_backups)
if (ibox->index_never_in_memory) {
"Couldn't create index file");
return -1;
}
}
if (create_missing_index_dir(box) < 0)
return -1;
/* newly created index directory. update its stat. */
}
}
if (ibox->index_never_in_memory) {
return -1;
}
/* try opening once more. it should be created
directly into memory now. */
lock_method) < 0)
i_panic("in-memory index creation failed");
}
}
if (hook_mailbox_index_opened != NULL)
return 0;
}
enum mailbox_flags flags,
const char *index_prefix)
{
const char *path;
else {
}
}
ibox->commit_log_file_seq = 0;
}
enum mailbox_feature feature)
{
if ((feature & MAILBOX_FEATURE_CONDSTORE) != 0) {
if (mailbox_open(box) < 0)
return -1;
}
}
return 0;
}
{
}
{
}
{
/* FIXME: return FALSE if we're full */
return !index_storage_is_readonly(box);
}
{
}
{
}
const char **error_r)
{
unsigned int i, idx;
/* if it already exists, skip validity checks */
return TRUE;
if (*keyword == '\0') {
*error_r = "Empty keywords not allowed";
return FALSE;
}
/* these are IMAP-specific restrictions, but for now IMAP is all we
care about */
for (i = 0; keyword[i] != '\0'; i++) {
if (IS_ATOM_SPECIAL((unsigned char)keyword[i])) {
*error_r = "Invalid characters in keyword";
return FALSE;
}
if ((unsigned char)keyword[i] >= 0x80) {
*error_r = "8bit characters in keyword";
return FALSE;
}
}
*error_r = "Keyword length too long";
return FALSE;
}
return TRUE;
}
static struct mail_keywords *
const char *const keywords[])
{
ARRAY_DEFINE(valid_keywords, const char *);
const char *error;
}
}
{
const char *error;
unsigned int i;
continue;
if (!skip_invalid) {
return -1;
}
/* found invalid keywords, do this the slow way */
T_BEGIN {
keywords);
} T_END;
return 0;
}
return 0;
}
struct mail_keywords *
{
}
{
}
{
}