mail-index-map.c revision 35111acf4f63ef944ac25c1f0c2eb5c2c5b0161e
6bdda696b3ea703c47e87fea61017ec655f91d92nd/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
6bdda696b3ea703c47e87fea61017ec655f91d92ndstatic void mail_index_map_init_extbufs(struct mail_index_map *map,
6bdda696b3ea703c47e87fea61017ec655f91d92nd unsigned int initial_count)
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* try to use the existing pool's size for initial_count so
6bdda696b3ea703c47e87fea61017ec655f91d92nd we don't grow it unneededly */
6bdda696b3ea703c47e87fea61017ec655f91d92nd p_array_init(&map->extensions, map->extension_pool, initial_count);
6bdda696b3ea703c47e87fea61017ec655f91d92nd p_array_init(&map->ext_id_map, map->extension_pool, initial_count);
6bdda696b3ea703c47e87fea61017ec655f91d92ndbool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
6bdda696b3ea703c47e87fea61017ec655f91d92nd unsigned int i, size;
6bdda696b3ea703c47e87fea61017ec655f91d92nd for (i = 0; i < size; i++) {
6bdda696b3ea703c47e87fea61017ec655f91d92ndunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len)
6bdda696b3ea703c47e87fea61017ec655f91d92nd size_t size = sizeof(struct mail_index_ext_header) + name_len;
6bdda696b3ea703c47e87fea61017ec655f91d92nd ext->index_idx = mail_index_ext_register(map->index, name,
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* Update index ext_id -> map ext_id mapping. Fill non-used
6bdda696b3ea703c47e87fea61017ec655f91d92nd ext_ids with (uint32_t)-1 */
ac7985784d08a3655291f24f711812b4d8b1cbcffuankgint mail_index_map_ext_get_next(struct mail_index_map *map,
6bdda696b3ea703c47e87fea61017ec655f91d92nd unsigned int *offset_p,
6bdda696b3ea703c47e87fea61017ec655f91d92nd const char **name_r)
0662ed52e814f8f08ef0e09956413a792584eddffuankg /* Extension header contains:
6bdda696b3ea703c47e87fea61017ec655f91d92nd - struct mail_index_ext_header
6bdda696b3ea703c47e87fea61017ec655f91d92nd - name (not 0-terminated)
6bdda696b3ea703c47e87fea61017ec655f91d92nd - 64bit alignment padding
6bdda696b3ea703c47e87fea61017ec655f91d92nd - extension header contents
0662ed52e814f8f08ef0e09956413a792584eddffuankg - 64bit alignment padding
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd offset += mail_index_map_ext_hdr_offset(ext_hdr->name_size);
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd *name_r = t_strndup(CONST_PTR_OFFSET(map->hdr_base, name_offset),
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg if (strcmp(*name_r, str_sanitize(*name_r, -1)) != 0) {
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* we allow only plain ASCII names, so this extension
6bdda696b3ea703c47e87fea61017ec655f91d92nd is most likely broken */
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* finally make sure that the hdr_size is small enough.
6bdda696b3ea703c47e87fea61017ec655f91d92nd do this last so that we could return a usable name. */
6bdda696b3ea703c47e87fea61017ec655f91d92nd offset += MAIL_INDEX_HEADER_SIZE_ALIGN(ext_hdr->hdr_size);
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92ndint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
6bdda696b3ea703c47e87fea61017ec655f91d92nd if ((ext_hdr->record_size == 0 && ext_hdr->hdr_size == 0) ||
6bdda696b3ea703c47e87fea61017ec655f91d92nd (ext_hdr->record_align == 0 && ext_hdr->record_size != 0)) {
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* if we get here from extension introduction, record_offset=0 and
cf7ca2f9eaa6523fefcccba4287b91637391fb51fuankg hdr->record_size hasn't been updated yet */
6bdda696b3ea703c47e87fea61017ec655f91d92nd ext_hdr->record_offset + ext_hdr->record_size > hdr->record_size) {
6bdda696b3ea703c47e87fea61017ec655f91d92nd "outside record size (%u+%u > %u)",
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd *error_r = t_strdup_printf("Record size not aligned by %u "
6bdda696b3ea703c47e87fea61017ec655f91d92nd "as required by extension",
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd if (ext_hdr->hdr_size > MAIL_INDEX_EXT_HEADER_MAX_SIZE) {
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
8ffac2c334103c0336602aaede650cb578611151fuankgstatic int mail_index_map_parse_extensions(struct mail_index_map *map)
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* extension headers always start from 64bit offsets, so if base header
6bdda696b3ea703c47e87fea61017ec655f91d92nd doesn't happen to be 64bit aligned we'll skip some bytes */
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg offset = MAIL_INDEX_HEADER_SIZE_ALIGN(map->hdr.base_header_size);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg if (offset >= map->hdr.header_size && map->extension_pool == NULL) {
6bdda696b3ea703c47e87fea61017ec655f91d92nd /* nothing to do, skip allocatations and all */
6bdda696b3ea703c47e87fea61017ec655f91d92nd for (i = 0; i < old_count; i++)
0662ed52e814f8f08ef0e09956413a792584eddffuankg mail_index_set_error(index, "Corrupted index file %s: "
6bdda696b3ea703c47e87fea61017ec655f91d92nd "Header extension #%d (%s) goes outside header",
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
6bdda696b3ea703c47e87fea61017ec655f91d92nd "Broken extension #%d (%s): %s",
6bdda696b3ea703c47e87fea61017ec655f91d92nd return -1;
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg "Duplicate header extension %s",
const char *name;
#ifdef DEBUG
const unsigned int *old_idx;
unsigned int kw_idx;
unsigned int kw_idx;
#if !WORDS_BIGENDIAN
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
sizeof(struct mail_index_record));
int ret;
pos = 0;
if (ret > 0)
return ret;
const void *buf;
pos);
if (ret > 0) {
extra = 0;
extra);
if (ret < 0) {
if (ret == 0) {
unsigned int *lock_id)
unsigned int i, count;
int ret;
for (i = 0; i < count; i++)
ret = 0;
*lock_id = 0;
if (ret <= 0) {
if (ret == 0) {
return ret;
#if !WORDS_BIGENDIAN
unsigned int lock_id;
if (ret <= 0) {
if (ret < 0)
if (use_mmap) {
if (ret == 0) {
ret = 0;
ret = 0;
} T_END;
if (ret < 0) {
ret = 0;
if (ret <= 0) {
int ret;
ret = 0;
if (ret == 0) {
TRUE);
return ret;
unsigned int i, count;
for (i = 0; i < count; i++) {
i_unreached();
unsigned int record_size)
static struct mail_index_record_map *
return rec_map;
unsigned int i, count;
for (i = 0; i < count; i++) {
return mem_map;
return FALSE;