mail-index.c revision 7e94cf9d70ce9fdeccb7a85ff400b899e6386f36
/* Copyright (C) 2003-2004 Timo Sirainen */
#include "lib.h"
#include "buffer.h"
#include "file-lock.h"
#include "mmap-util.h"
#include "read-full.h"
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-transaction-log.h"
#include "mail-cache.h"
#include <stdio.h>
#include <stddef.h>
#include <time.h>
{
struct mail_index *index;
return index;
}
{
}
{
struct mail_index_extra_record_info info;
unsigned int i;
/* see if it's there already */
for (i = 0; i < index->extra_records_count; i++) {
return i;
}
}
i_panic("Maximum extra record count reached, "
"you'll need to recompile with larger limit. "
"MAIL_INDEX_MAX_EXTRA_RECORDS = %d",
}
}
struct mail_index_map *map)
{
#ifndef WORDS_BIGENDIAN
#endif
/* major version change - handle silently(?) */
return -1;
}
/* architecture change - handle silently(?) */
return -1;
}
/* we've already complained about it */
return -1;
}
/* following some extra checks that only take a bit of CPU */
"uid_validity = 0, next_uid = %u",
return -1;
}
"keywords_mask_size mismatch: %d != %d",
(int)sizeof(keywords_mask_t));
return -1;
}
"record_size too small: %u < %"PRIuSIZE_T,
sizeof(struct mail_index_record));
return -1;
}
return 0;
return 0;
return 0;
return 1;
}
struct mail_index_map *map)
{
}
map->mmap_used_size = 0;
map->records_count = 0;
}
}
{
return;
}
struct mail_index_map *map)
{
}
{
const struct mail_index_header *hdr;
unsigned int records_count;
/* we had temporarily used a buffer, eg. for updating index */
}
return -1;
}
return 0;
}
"messages_count too large (%u > %u)",
return 0;
}
/* header smaller than ours, make a copy so our newer headers
won't have garbage in them */
}
return 1;
}
struct mail_index_map *map)
{
struct mail_index_header hdr;
ret = 1;
if (ret > 0)
}
(size_t)-1);
}
/* @UNSAFE */
}
if (ret < 0) {
return 0;
return -1;
}
if (ret == 0) {
"Unexpected EOF while reading index file");
return -1;
}
return 1;
}
struct mail_index_map *map)
{
int i, ret;
for (i = 0; i < MAIL_INDEX_ESTALE_RETRY_COUNT; i++) {
if (ret != 0)
return ret;
/* ESTALE - reopen index file */
if (ret <= 0) {
if (ret == 0) {
/* the file was lost */
}
return -1;
}
}
/* Too many ESTALE retries */
return -1;
}
{
const struct mail_index_header *hdr;
struct mail_index_map *map;
int ret;
} else if (MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
if (map->write_to_disk) {
/* we have modified this mapping and it's waiting to
be written to disk once we drop exclusive lock.
mapping couldn't have changed, so do nothing. */
return 1;
}
/* FIXME: we need to re-read header */
/* see if re-mmaping is needed (file has grown) */
/* always check corrupted-flag to avoid errors later */
return -1;
return 1;
}
}
if (!index->mmap_disable) {
return ret;
}
} else {
return -1;
}
}
if (ret < 0) {
return 0;
}
if (ret == 0)
return 1;
}
struct mail_index_map *
{
struct mail_index_map *mem_map;
unsigned int i;
if (MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
return map;
}
else {
for (i = 0; i < map->records_count; i++) {
}
}
return mem_map;
}
{
int i;
for (i = 0; i < 3; i++) {
}
break;
/* May happen with some OSes with NFS. Try again, although
there's still a race condition with another computer
creating the index file again. However, we can't try forever
as ESTALE happens also if index directory has been deleted
from server.. */
}
/* have to create it */
return 0;
}
return 1;
}
static int
{
unsigned int lock_id;
int ret;
*lock_id_r = 0;
if (ret <= 0)
return ret;
return -1;
if (ret == 0) {
/* it's corrupted - recreate it */
*lock_id_r = 0;
} else {
else
}
return ret;
}
const struct mail_index_header *hdr)
{
} else {
return -1;
}
}
return 0;
}
{
const char *path;
int fd;
if (fd == -1)
return -1;
}
return fd;
}
struct mail_index_header *hdr)
{
const char *path;
int ret;
/* log file lock protects index creation */
return -1;
if (ret != 0) {
return ret < 0 ? -1 : 0;
}
/* create it fully in index.tmp first */
ret = -1;
ret = -1;
} else {
}
if (ret == 0) {
/* it's corrupted even while we just created it,
should never happen unless someone pokes the file directly */
"Newly created index file is corrupted: %s", path);
ret = -1;
}
if (ret < 0) {
"unlink()");
}
} else {
/* make it visible to others */
ret = -1;
}
}
return ret;
}
struct mail_index_header *hdr)
{
#ifndef WORDS_BIGENDIAN
#endif
}
/* returns -1 = error, 0 = won't create, 1 = ok */
enum mail_index_open_flags flags)
{
struct mail_index_header hdr;
unsigned int lock_id = 0;
int ret;
if (ret > 0)
else if (ret == 0) {
/* doesn't exist, or corrupted */
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
return 0;
} else if (ret < 0)
return -1;
return -1;
if (lock_id != 0) {
lock_id = 0;
}
return -1;
}
if (lock_id == 0) {
return -1;
}
return -1;
return 1;
}
{
int i = 0, ret;
return 0;
do {
index->shared_lock_count = 0;
index->excl_lock_count = 0;
(flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
(flags & MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE) != 0;
if (ret <= 0)
break;
if (ret == 0) {
/* completely broken, reopen */
if (i++ < 3)
continue;
/* too many tries */
ret = -1;
}
}
break;
} while (1);
if (ret <= 0)
return ret;
}
{
}
}
}
}
}
{
struct mail_index_map *old_map;
/* new file, new locks. the old fd can keep it's locks, they don't
matter anymore as no-one's going to modify the file. */
index->shared_lock_count = 0;
if (fd != -1) {
ret = 0;
} else {
if (ret > 0)
else if (ret == 0) {
/* index file is lost */
ret = -1;
}
}
if (ret == 0) {
ret = -1;
}
if (lock_id != 0)
if (ret == 0) {
} else {
}
}
return ret;
}
{
return -1;
/* lost it? recreate */
(void)mail_index_mark_corrupted(index);
return -1;
}
return -1;
return 1;
} else {
return 0;
}
}
{
}
{
else {
}
return -1;
}
{
}
{
struct mail_index_header hdr;
return;
/* make sure we can write the header */
PROT_READ | PROT_WRITE) < 0) {
return;
}
}
}
}
const char *function)
{
return -1;
}
}
const char *filepath,
const char *function)
{
return -1;
}
}
{
if (index->nodiskspace)
return MAIL_INDEX_ERROR_DISKSPACE;
return MAIL_INDEX_ERROR_INTERNAL;
return MAIL_INDEX_ERROR_NONE;
}
{
}
{
}
}
{
return FALSE; // FIXME
}