mail-index-sync-ext.c revision dbccc82512389d0f1fda99245095ba4adbad1090
/* Copyright (c) 2004-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"
#include "mail-transaction-log.h"
#include <stdlib.h>
{
const struct mail_index_ext *ext;
const struct mail_index_registered_ext *rext;
void **contexts;
struct mail_index_expunge_handler eh;
unsigned int ext_count, id_map_count;
unsigned int rext_count, context_count;
return;
else
continue;
}
}
void
{
const struct mail_index_expunge_handler *eh;
unsigned int i, count;
return;
for (i = 0; i < count; i++) {
}
}
}
{
unsigned int count;
return;
/* set space for extra contexts */
/* make sure the extra_contexts contains everything */
/* we need to update the expunge handler list in case they had
already been called */
}
{
const struct mail_index_registered_ext *rext;
void **extra_contexts;
unsigned int i, rext_count, context_count;
return;
for (i = 0; i < context_count; i++) {
if (extra_contexts[i] != NULL) {
&extra_contexts[i]);
}
}
}
static struct mail_index_ext_header *
{
struct mail_index_ext_header *ext_hdr;
void *hdr_base;
/* do some kludgy jumping to get to it. */
return ext_hdr;
}
{
}
{
struct mail_index_ext_header *ext_hdr;
unsigned int i, count;
const void *src;
/* @UNSAFE */
for (i = 0; i < count; i++) {
ext[i].record_offset = 0;
}
/* we are growing the extension record. remember this
so we don't write extra data while copying the record */
}
/* we simply try to use the extensions with largest alignment
requirement first. FIXME: if the extension sizes don't match
alignmentation, this may not give the minimal layout. */
offset = sizeof(struct mail_index_record);
for (;;) {
for (i = 0; i < count; i++) {
if (sorted[i]->record_offset == 0 &&
sorted[i]->record_size > 0) {
break;
}
}
if (i == count) {
/* all done */
break;
}
/* we have to leave space here */
} else {
}
}
/* keep record size divisible with maximum alignment */
}
/* copy the records to new buffer */
offset = 0;
/* write the base record */
sizeof(struct mail_index_record));
/* write extensions */
for (i = 0; i < count; i++) {
copy_sizes[i]);
}
}
/* we didn't fully write the last record */
}
/* update record offsets in headers */
for (i = 0; i < count; i++) {
}
}
static void
sync_ext_resize(const struct mail_transaction_ext_intro *u,
{
struct mail_index_ext *ext;
struct mail_index_ext_header *ext_hdr;
/* header shrank */
/* header grown */
}
if (old_record_size != u->record_size)
if (modified) {
}
/* move all hdr_offset of all extensions after this one */
}
}
if (old_record_size != u->record_size) {
} else if (modified) {
/* header size changed. recreate index file. */
}
}
static bool
{
unsigned char *p;
}
if (*p != 0) {
/* we've already complained once */
return FALSE;
}
*p = 1;
return TRUE;
}
const struct mail_transaction_ext_intro *u)
{
struct mail_index_ext_header ext_hdr;
const struct mail_index_ext *ext;
/* default to ignoring the following extension updates in case this
intro is corrupted */
ctx->cur_ext_map_idx = 0;
return -1;
"Extension introduction for unknown id %u", u->ext_id);
return -1;
}
"Extension introduction without id or name");
return -1;
}
ext_map_idx = u->ext_id;
} else {
}
/* Keyword extension is handled internally by the keyword
code. Any attempt to modify them directly could cause
assert-crashes later, so prevent them immediately. */
"Extension introduction for keywords");
return -1;
}
/* exists already */
/* check if we need to resize anything */
} else {
/* extension was reset and this transaction hadn't
yet seen it. ignore this update. */
}
return 1;
}
/* be sure to get a unique mapping before we modify the extensions,
otherwise other map users will see the new extension but not the
data records that sync_ext_reorder() adds. */
/* we need to add padding between base header and extensions */
}
"Broken extension introduction: %s", error);
return -1;
}
/* register record offset initially using zero,
sync_ext_reorder() will fix it. */
&ext_hdr);
/* <ext_hdr> <name> [padding] [header data] */
/* header must begin and end in correct alignment */
return 1;
}
const struct mail_transaction_ext_reset *u)
{
struct mail_index_ext_header *ext_hdr;
struct mail_index_ext *ext;
struct mail_index_record *rec;
uint32_t i;
"Extension reset without intro prefix");
return -1;
}
if (ctx->cur_ext_ignore)
return 1;
/* a new index file will be created, so the old data won't be
accidentally used by other processes. */
ext->record_size);
}
return 1;
}
int
const struct mail_transaction_ext_hdr_update *u)
{
const struct mail_index_ext *ext;
"Extension header update without intro prefix");
return -1;
}
if (ctx->cur_ext_ignore)
return 1;
u + 1, u->size);
return 1;
}
int
const struct mail_transaction_ext_rec_update *u)
{
struct mail_index_record *rec;
const struct mail_index_ext *ext;
const struct mail_index_registered_ext *rext;
void *old_data;
int ret;
"Extension record update for invalid uid=%u", u->uid);
return -1;
}
return 1;
/* call sync handlers only when its registered type matches with
void **extra_context =
if (ret <= 0)
return ret;
}
/* @UNSAFE */
return 1;
}