mail-index.c revision 5aeb15e5817fbd4b1d8de540aa7673e3819a8030
/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "buffer.h"
#include "hash.h"
#include "str-sanitize.h"
#include "mmap-util.h"
#include "nfs-workarounds.h"
#include "read-full.h"
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"
#include "mail-index-modseq.h"
#include "mail-transaction-log.h"
#include "mail-cache.h"
#include <stdio.h>
#include <stddef.h>
#include <time.h>
struct mail_index_module_register mail_index_module_register = { 0 };
{
struct mail_index *index;
128, 2, 1);
return index;
}
{
}
{
}
{
}
{
struct mail_index_registered_ext rext;
if (default_record_size != 0 && default_record_align == 0) {
i_panic("mail_index_ext_register(%s): "
"Invalid record alignment", name);
}
return ext_id;
}
{
const struct mail_index_registered_ext *extensions;
unsigned int i, count;
for (i = 0; i < count; i++) {
*ext_id_r = i;
return TRUE;
}
}
return FALSE;
}
void *context)
{
struct mail_index_registered_ext *rext;
}
{
struct mail_index_registered_ext *rext;
}
{
struct mail_index_registered_ext *rext;
}
{
struct mail_index_registered_ext *rext;
}
{
}
{
mail_index_sync_lost_handler_t *const *handlers;
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
}
}
{
void *value;
/* keywords_hash keeps a name => index mapping of keywords.
Keywords are never removed from it, so the index values are valid
for the lifetime of the mail_index. */
return TRUE;
}
*idx_r = (unsigned int)-1;
return FALSE;
}
const char *keyword,
unsigned int *idx_r)
{
char *keyword_dup;
return;
}
{
}
{
/* Note that our caller must close index->fd by itself. */
else {
}
}
/* have to create it */
return 0;
}
return 1;
}
static int
{
int ret;
if (MAIL_INDEX_IS_IN_MEMORY(index))
return 0;
if (ret == 0) {
/* it's corrupted - recreate it */
}
}
return ret;
}
{
const char *path;
int fd;
if (fd == -1)
return -1;
}
return fd;
}
enum mail_index_open_flags flags)
{
int ret;
if (ret == 0) {
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
return 0;
/* if dovecot.index exists, read it first so that we can get
the correct indexid and log sequence */
(void)mail_index_try_open(index);
/* Create a new indexid for us. If we're opening index
into memory, index->map doesn't exist yet. */
}
}
if (ret >= 0) {
if (ret == 0) {
/* corrupted */
if (ret == 0) {
}
}
}
if (ret < 0) {
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
return -1;
if (mail_index_move_to_memory(index) < 0)
return -1;
}
return 1;
}
enum file_lock_method lock_method)
{
int ret;
MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
/* corrupted, reopen files */
} else {
return 1;
}
}
i_strdup("(in-memory index)") :
index->shared_lock_count = 0;
index->excl_lock_count = 0;
(flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0;
(flags & MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE) != 0;
i_fatal("nfs flush requires fsync_disable=no");
i_fatal("nfs flush requires mmap_disable=yes");
/* doesn't exist and create flag not used */
return ret;
}
return 1;
}
{
}
index->shared_lock_count = 0;
index->excl_lock_count = 0;
}
{
}
{
if (MAIL_INDEX_IS_IN_MEMORY(index))
return 0;
return mail_index_try_open_only(index);
return 0;
}
/* the same file */
return 1;
}
/* new file, new locks. the old fd can keep its locks, they don't
matter anymore as no-one's going to modify the file. */
return mail_index_try_open_only(index);
}
{
int ret;
return ret <= 0 ? -1 : 0;
}
{
}
{
else {
}
return -1;
}
{
struct mail_index_map *map;
if (MAIL_INDEX_IS_IN_MEMORY(index))
/* set the index as being into memory */
/* index was never even opened. just mark it as being in
memory and let the caller re-open the index. */
return -1;
}
/* move index map to memory */
}
/* move transaction log to memory */
}
}
return 0;
}
{
return MAIL_INDEX_IS_IN_MEMORY(index);
}
{
}
const char *function)
{
return -1;
}
}
const char *filepath,
const char *function)
{
return -1;
}
}
{
}
{
}
}
#ifdef WORDS_BIGENDIAN
/* FIXME: Unfortunately these functions were originally written to use
endian-specific code and we can't avoid that without breaking backwards
compatibility. When we do break it, just select one of these. */
{
offset >>= 2;
}
{
return 0;
return (((offset & 0x0000007f)) |
}
#else
{
offset >>= 2;
}
{
return 0;
}
#endif
{
/* number continues as long as the highest bit is set */
while (num >= 0x80) {
*p += 1;
num >>= 7;
}
**p = num;
*p += 1;
}
{
const uint8_t *c = *p;
unsigned int bits = 0;
for (;;) {
/* we should never see EOF */
*num_r = 0;
return -1;
}
if (*c < 0x80)
break;
bits += 7;
c++;
}
/* broken input */
*p = end;
*num_r = 0;
return -1;
}
*p = c + 1;
return 0;
}