index-storage.c revision e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85
/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "istream.h"
#include "ioloop.h"
#include "str.h"
#include "imap-parser.h"
#include "mkdir-parents.h"
#include "mail-index-alloc-cache.h"
#include "mail-index-private.h"
#include "mail-index-modseq.h"
#include "mailbox-log.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>
#define LOCK_NOTIFY_INTERVAL 30
struct index_storage_module index_storage_module =
const char *name)
{
const char *origin, *parent_origin;
int n = 0;
return 0;
break;
"mkdir(%s) failed: %m", index_dir);
return -1;
}
/* create the parent directory first */
&parent_gid, &parent_origin);
parent_gid, parent_origin) < 0 &&
"mkdir(%s) failed: %m", parent_dir);
return -1;
}
}
return 0;
}
static struct mail_index *
{
const char *index_dir, *mailbox_path;
if (*index_dir == '\0')
}
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 =
int ret;
if (move_to_memory)
if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) {
"Couldn't create index file");
return -1;
}
}
return -1;
}
if (ret <= 0 || move_to_memory) {
if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) {
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_opened != NULL)
return -1;
}
}
return 0;
}
enum mailbox_flags flags,
const char *index_prefix)
{
struct index_mailbox_context *ibox;
const char *path;
if (box->file_create_mode == 0)
}
enum mailbox_feature feature)
{
if ((feature & MAILBOX_FEATURE_CONDSTORE) != 0) {
if (mailbox_open(box) < 0)
return -1;
T_BEGIN {
} T_END;
}
return 0;
}
{
ibox->recent_flags_prev_uid = 0;
ibox->recent_flags_count = 0;
ibox->sync_last_check = 0;
}
static void
const struct mailbox_update *update)
{
const struct mail_cache_field *old_fields;
struct mail_cache_field field;
unsigned int i, j, old_count;
&old_count);
/* There shouldn't be many fields, so don't worry about O(n^2). */
for (i = 0; field_names[i] != NULL; i++) {
/* see if it's an existing field */
for (j = 0; j < old_count; j++) {
break;
}
if (j != old_count) {
field = old_fields[j];
/* new header */
} else {
/* new unknown field. we can't do anything about
this since we don't know its type */
}
}
if (array_count(&new_fields) > 0) {
}
}
const struct mailbox_update *update)
{
const struct mail_index_header *hdr;
struct mail_index_view *view;
struct mail_index_transaction *trans;
int ret;
if (mailbox_open(box) < 0)
return -1;
/* make sure we get the latest index info */
if (update->uid_validity != 0 &&
}
if (update->min_next_uid != 0 &&
}
if (update->min_highest_modseq != 0 &&
}
return ret;
}
{
enum mail_error error;
return 0;
return -1;
}
/* failed directory deletion, but mailbox deletion succeeded.
this was probably maildir++, which internally deleted the
directory as well. add changelog record about that too. */
return 0;
}
{
/* \noselect mailbox, try deleting only the directory */
}
return -1;
/* Make sure the indexes are closed before trying to delete the
directory that contains them. It can still fail with some NFS
implementations if indexes are opened by another session, but
that can't really be helped. */
return -1;
}
}
{
}
{
/* 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 {
} T_END;
return 0;
}
return 0;
}
struct mail_keywords *
{
}
{
}
{
}
{
}