index-mailbox-list.c revision 5694eeb99b69dea8033ca77ad69743c6b4871370
/* Copyright (C) 2006 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "file-lock.h"
#include "imap-match.h"
#include "mail-index.h"
#include "mail-storage.h"
#include "mailbox-list-index.h"
#include "index-mailbox-list.h"
#include <stdlib.h>
#include <time.h>
/* min 2 seconds */
#define MAILBOX_LIST_SYNC_SECS 2
static int
{
struct mail_index_view_sync_ctx *sync_ctx;
struct mail_index_view_sync_rec sync_rec;
int ret;
&sync_ctx) < 0) {
return -1;
}
return ret;
}
static int
{
const struct mail_index_header *hdr;
if (index_mailbox_view_sync(ctx) < 0)
return -1;
/* FIXME: single sync_stamp works only with maildir++ */
"stat(%s) failed: %m", path);
return -1;
}
/*
if mtime is older than 2 secs, we set the first bit on
if mtime is 0-2 secs old, we set the first bit off.
this way we'll always do a resync later when syncing a recently
changed directory. if the directory changes while we're syncing it
we'll resync it again later.
this would work with 1 second difference if we didn't store the
dirtyness flag in the stamp's first bit.
*/
else
}
const char **prefix_r, int *recurse_level_r)
{
const char *prefix_start, *prefix_end;
bool seen_wildcards = FALSE;
int recurse_level = 0;
if (*mask == '%')
else if (*mask == '*') {
recurse_level = -1;
break;
}
if (!seen_wildcards)
prefix_end = mask;
}
}
}
static struct mailbox_list_iterate_context *
enum mailbox_list_iter_flags flags)
{
struct index_mailbox_list_iterate_context *ctx;
const char *prefix;
int recurse_level;
if ((flags & MAILBOX_LIST_ITER_RAW_LIST) != 0) {
/* Ignore indexes completely */
} else if (index_mailbox_list_is_synced(ctx) > 0) {
/* synced, list from index */
} else {
/* FIXME: this works nicely with maildir++, but not others */
mask = "*";
prefix = "";
}
}
}
static enum mailbox_info_flags
{
enum mailbox_info_flags info_flags = 0;
if ((flags & MAILBOX_LIST_INDEX_FLAG_CHILDREN) != 0)
if ((flags & MAILBOX_LIST_INDEX_FLAG_NOCHILDREN) != 0)
if ((flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
if ((flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
return info_flags;
}
static enum mailbox_list_index_flags
{
enum mailbox_list_index_flags flags = 0;
if ((info_flags & MAILBOX_CHILDREN) != 0)
if ((info_flags & MAILBOX_NOCHILDREN) != 0)
if ((info_flags & MAILBOX_NONEXISTENT) != 0)
if ((info_flags & MAILBOX_NOSELECT) != 0)
return flags;
}
/* skip nonexistent mailboxes when finding with "*" */
(ctx)->recurse_level >= 0)
struct mailbox_info **info_r)
{
struct mailbox_list_index_info iinfo;
const struct mail_index_record *rec;
int ret;
/* find the next matching mailbox */
do {
if (ret <= 0) {
return ret;
}
/* get the mailbox's flags */
return -1;
if (seq == 0) {
"Desynced: Record expunged from mail index");
return -1;
}
return -1;
/* do some sanity checks to the flags */
"Mail index has both children and nochildren flags");
return -1;
}
"Desynced: Children flags wrong in mail index");
return -1;
}
return 0;
}
static struct mailbox_info *
{
struct index_mailbox_list_iterate_context *ctx =
(struct index_mailbox_list_iterate_context *)_ctx;
struct mailbox_info *info;
return NULL;
}
return info;
}
do {
return info;
/* if the sync fails, just ignore it. we don't require synced
indexes to return valid output. */
&seq) == 0) {
flags);
}
return info;
}
static int
{
struct index_mailbox_list_iterate_context *ctx =
(struct index_mailbox_list_iterate_context *)_ctx;
}
/* FIXME: single sync_stamp works only with maildir++ */
if (ret < 0)
else {
/* index updates aren't that important. if the commit
fails, we've still returned full output. */
}
}
return ret;
}
{
}
const char *dir)
{
const char *path;
int ret;
/* FIXME: a bit ugly way to get the flags, but this will do for now.. */
if ((storage_flags & MAIL_STORAGE_FLAG_MMAP_DISABLE) != 0)
#ifndef MMAP_CONFLICTS_WRITE
if ((storage_flags & MAIL_STORAGE_FLAG_MMAP_NO_WRITE) != 0)
#endif
/* try opening once more. it should be created
directly into memory now. */
if (ret <= 0) {
/* everything failed. there's a bug in the
code, but just work around it by disabling
the index completely */
return -1;
}
}
}
ilist->mail_index);
/* skip indexing */
return -1;
}
NULL);
return 0;
}
{
const char *dir;
/* FIXME: for now we only work with maildir++ */
/* reserve the module context anyway, so syncing code knows
that the index is disabled */
return;
}
/* sync_init allocates the extensions. do it here before opening the
index files, so that our initial memory pool size guesses are a
bit more optimal */
}
}
void index_mailbox_list_init(void); /* called in mailbox-list-register.c */
void index_mailbox_list_init(void)
{
}