mail-index-sync-keywords.c revision 5aeb15e5817fbd4b1d8de540aa7673e3819a8030
/* Copyright (c) 2004-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "mail-index-modseq.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"
#include "mail-transaction-log.h"
static bool
const char *keyword_name, unsigned int *idx_r)
{
const unsigned int *idx_map;
unsigned int i, count, keyword_idx;
&keyword_idx)) {
/* FIXME: slow. maybe create index -> file mapping as well */
for (i = 0; i < count; i++) {
if (idx_map[i] == keyword_idx) {
*idx_r = i;
return TRUE;
}
}
}
return FALSE;
}
static buffer_t *
const struct mail_index_ext *ext,
unsigned int new_count, unsigned int *keywords_count_r,
{
const struct mail_index_keyword_header *kw_hdr;
const struct mail_index_keyword_header_rec *kw_rec;
const char *name;
struct mail_index_keyword_header new_kw_hdr;
if (kw_hdr->keywords_count == 0)
return NULL;
new_kw_hdr = *kw_hdr;
*name_offset_r = offset;
return buf;
}
{
struct mail_transaction_ext_intro *u;
i_assert(keywords_count > 0);
buffer_create_static_hard(pool_datastack_create(), sizeof(*u) +
sizeof(MAIL_INDEX_EXT_KEYWORDS)-1);
u = buffer_append_space_unsafe(ext_intro_buf, sizeof(*u));
u->ext_id = ext_map_idx;
if ((u->record_size % 4) != 0) {
/* since we aren't properly aligned anyway,
reserve one extra byte for future */
u->record_size++;
}
u->record_align = 1;
u->name_size);
}
if (mail_index_sync_ext_intro(ctx, u) < 0)
i_panic("Keyword extension growing failed");
}
static void
const char *keyword_name, unsigned int *keyword_idx_r)
{
struct mail_index_map *map;
struct mail_index_keyword_header *kw_hdr;
struct mail_index_keyword_header_rec kw_rec;
unsigned int keywords_count;
/* if we crash in the middle of writing the header, the
keywords are more or less corrupted. avoid that by
making sure the header is updated atomically. */
&ext_map_idx))
else {
/* update existing header */
&name_offset);
}
/* create new / replace broken header */
name_offset = 0;
}
/* add the keyword */
rec_offset += sizeof(kw_rec);
/* if we need to grow the buffer, add some padding */
/* map may have changed */
&ext_map_idx))
i_unreached();
}
if (mail_index_map_parse_keywords(map) < 0)
i_panic("Keyword update corrupted keywords header");
}
static int
const struct mail_index_ext *ext,
{
struct mail_index_record *rec;
unsigned int data_offset;
return 1;
switch (type) {
case MODIFY_ADD:
}
break;
case MODIFY_REMOVE:
}
break;
default:
i_unreached();
}
return 1;
}
const struct mail_transaction_header *hdr,
const struct mail_transaction_keyword_update *rec)
{
const char *keyword_name;
const struct mail_index_ext *ext;
unsigned int keyword_idx;
int ret;
if ((seqset_offset % 4) != 0)
if (*keyword_name == '\0') {
"Trying to use empty keyword");
return -1;
}
/* if the keyword wasn't found, the "keywords" extension was created.
if it was found, the record size should already be correct, but
in case it isn't just fix it ourself. */
&ext_map_idx))
i_unreached();
/* nothing to do */
return 1;
}
/* grow the record size */
&ext_map_idx))
i_unreached();
}
if (ret <= 0)
return ret;
uid += 2;
}
return 1;
}
int
const struct mail_transaction_header *hdr,
const struct mail_transaction_keyword_reset *r)
{
struct mail_index_record *rec;
const struct mail_index_ext *ext;
const struct mail_transaction_keyword_reset *end;
&ext_map_idx)) {
/* nothing to do */
return 1;
}
for (; r != end; r++) {
continue;
0, ext->record_size);
}
}
return 1;
}