mail-index-map-hdr.c revision 2f16d2e0b4408370cd44db359759b23a8c0656d3
/* Copyright (c) 2003-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "mail-index-private.h"
{
const struct mail_index_ext_header *ext_hdr;
/* extension headers always start from 64bit offsets, so if base header
doesn't happen to be 64bit aligned we'll skip some bytes */
/* nothing to do, skip allocatations and all */
return 0;
}
for (i = 0; i < old_count; i++)
ext_offset = offset;
"Header extension #%d (%s) goes outside header",
return -1;
}
"Broken extension #%d (%s): %s",
return -1;
}
"Duplicate header extension %s",
return -1;
}
}
return 0;
}
{
const struct mail_index_ext *ext;
const struct mail_index_keyword_header *kw_hdr;
const struct mail_index_keyword_header_rec *kw_rec;
const char *name;
unsigned int i, name_area_end_offset, old_count;
return 0;
}
/* Extension header contains:
- struct mail_index_keyword_header
- struct mail_index_keyword_header_rec * keywords_count
- const char names[] * keywords_count
*/
/* Keywords can only be added into same mapping. Removing requires a
new mapping (recreating the index file) */
/* nothing changed */
return 0;
}
/* make sure the header is valid */
"Keywords removed unexpectedly",
return -1;
}
"keywords_count larger than header size",
return -1;
}
for (i = 0; i < kw_hdr->keywords_count; i++) {
"name_offset points outside allocated header",
return -1;
}
}
"Keyword header doesn't end with NUL",
return -1;
}
/* create file -> index mapping */
#ifdef DEBUG
/* Check that existing headers are still the same. It's behind DEBUG
since it's pretty useless waste of CPU normally. */
const unsigned int *old_idx;
unsigned int kw_idx;
"Keywords changed unexpectedly",
return -1;
}
}
#endif
/* Register the newly seen keywords */
for (; i < kw_hdr->keywords_count; i++) {
unsigned int kw_idx;
if (*keyword == '\0') {
"Empty keyword name in header",
return -1;
}
}
return 0;
}
const struct mail_index_header *hdr,
{
enum mail_index_header_compat_flags compat_flags = 0;
#if !WORDS_BIGENDIAN
#endif
/* major version change - handle silently(?) */
return FALSE;
}
/* we've already complained about it */
return FALSE;
}
/* architecture change */
"CPU architecture changed",
return FALSE;
}
"Corrupted header sizes (base %u, full %u)",
hdr->header_size);
return FALSE;
}
return FALSE;
}
"indexid changed: %u -> %u",
}
}
return TRUE;
}
{
struct mail_index_record *rec;
}
}
{
return -1;
/* following some extra checks that only take a bit of CPU */
"record_size too small: %u < %"PRIuSIZE_T,
sizeof(struct mail_index_record));
return -1;
}
return 0;
return 0;
return 0;
return 0;
switch (hdr->minor_version) {
case 0:
/* upgrade silently from v1.0 */
if (hdr->first_recent_uid == 0)
/* fall through */
case 1:
/* pre-v1.1.rc6: make sure the \Recent flags are gone */
/* fall through */
case 2:
/* pre-v2.2 (although should have been done in v2.1 already):
make sure the old unused fields are cleared */
}
if (hdr->first_recent_uid == 0 ||
return 0;
if (hdr->messages_count > 0) {
/* last message's UID must be smaller than next_uid.
also make sure it's not zero. */
const struct mail_index_record *rec;
return 0;
}
return 1;
}