mail-transaction-log-view.c revision 6eb30032b4a50c383dea4c9c74342d906de6ad36
/* Copyright (C) 2003-2004 Timo Sirainen */
#include "lib.h"
#include "buffer.h"
#include "mail-index-private.h"
#include "mail-transaction-log-private.h"
#include "mail-transaction-util.h"
struct mail_transaction_log_view {
struct mail_transaction_log *log;
struct mail_transaction_log_view *next;
struct mail_transaction_header tmp_hdr;
unsigned int broken:1;
};
struct mail_transaction_log_view *
{
struct mail_transaction_log_view *view;
return view;
}
{
struct mail_transaction_log_view **p;
struct mail_transaction_log_file *file;
if (*p == view) {
break;
}
}
}
{
struct mail_transaction_log_view *view;
}
int
{
/* FIXME: error handling for "not found" case is bad.. should the
caller after all check it and handle as it sees best..? */
int ret;
return -1;
if (min_file_seq == 0) {
/* new index, transaction file not synced yet */
min_file_seq = 1;
min_file_offset = 0;
if (max_file_seq == 0) {
}
}
/* we can skip this */
min_file_offset = 0;
if (min_file_seq > max_file_seq) {
/* empty view */
}
}
/* find the oldest log file first. */
if (ret <= 0) {
if (ret == 0) {
"Lost transaction log file %s seq %u",
}
return -1;
}
if (min_file_offset == 0) {
/* this could happen if internal transactions haven't yet been
committed but external are. just assume we're at the
beginning. */
}
/* check these later than others as index file may have corrupted
log_file_offset. we should have recreated the log file and
skipped min_file_seq file above.. max_file_offset can be broken
only if min_file_seq = max_file_seq. */
if (ret <= 0) {
if (ret == 0) {
/* File is corrupted or stale NFS handle */
"Lost transaction log file %s seq %u",
}
return -1;
}
/* see if we could find the missing file */
if (ret <= 0) {
if (ret < 0)
return -1;
/* not found / corrupted */
}
}
/* we just wanted to sync everything */
break;
}
/* missing files in the middle */
"Lost transaction log file %s seq %u",
return -1;
}
if (ret == 0) {
/* File is corrupted or stale NFS handle */
"Lost transaction log file %s seq %u",
}
if (ret <= 0)
return -1;
}
/* we have all of them. update refcounts. */
/* unref old files */
} else {
/* going backwards, reference them */
}
/* reference all new files */
view->prev_file_seq = 0;
view->prev_file_offset = 0;
return 0;
}
void
{
}
void
const char *fmt, ...)
{
t_push();
t_pop();
}
int
{
}
static int
const struct mail_transaction_header **hdr_r,
const void **data_r)
{
const struct mail_transaction_header *hdr;
struct mail_transaction_log_file *file;
const struct mail_transaction_type_map *type_rec;
const void *data;
unsigned int record_size;
return 0;
/* prev_file_offset should point to beginning of previous log record.
when we reach EOF, it should be left there, not to beginning of the
next file. */
/* last file */
/* we're all finished */
return 0;
}
/* end of file, go to next one */
return 0;
}
"offset points outside file "
return -1;
}
record_size = 0;
} else {
else {
"unknown record type 0x%x",
return -1;
}
}
"record size too small (type=0x%x, size=%u)",
return -1;
}
"record size wrong (type 0x%x, %u %% %u != 0)",
return -1;
}
"record size too large (type=0x%x, offset=%"PRIuUOFF_T
return -1;
}
"found expunge without protection mask");
return -1;
}
"extra bits in header type: 0x%x",
return -1;
const struct mail_transaction_ext_intro *intro;
uint32_t i;
for (i = 0; i < hdr_size; ) {
/* should be just extra padding */
break;
}
"extension intro: name_size too large");
return -1;
}
}
}
return 1;
}
const struct mail_transaction_header **hdr_r,
{
const struct mail_transaction_header *hdr;
const void *data;
int ret = 0;
return -1;
/* looks like this is within our mask, but expunge
protection may mess up the check. */
break;
}
/* we don't want this record */
append isn't in mask */
}
if (ret < 0) {
return -1;
}
if (ret == 0)
return 0;
/* hide expunge protection */
}
return 1;
}