mail-index-sync-keywords.c revision bf045aa2e9c3846ecde84db303db6588b173bbae
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi/* Copyright (C) 2004 Timo Sirainen */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumikeyword_lookup(struct mail_index_sync_map_ctx *ctx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const char *keyword_name, unsigned int *idx_r)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const unsigned int *idx_map;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (mail_index_map_read_keywords(ctx->view->index, map) < 0)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (mail_index_keyword_lookup(ctx->view->index, keyword_name,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* FIXME: slow. maybe create index -> file mapping as well */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi idx_map = array_get(&map->keyword_idx_map, &count);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi for (i = 0; i < count; i++) {
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graberkeywords_get_header_buf(struct mail_index_map *map,
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber unsigned int new_count, unsigned int *keywords_count_r,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi size_t *rec_offset_r, size_t *name_offset_root_r,
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi const struct mail_index_keyword_header *kw_hdr;
8c3a756ed4cf22f9fdab5f95d067321e6ddcc425KATOH Yasufumi const struct mail_index_keyword_header_rec *kw_rec;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi name = (const char *)(kw_rec + kw_hdr->keywords_count);
8adef7614d4340b4ee44a4441fadd530f48515edKATOH Yasufumi *keywords_count_r = new_kw_hdr.keywords_count;
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi offset = kw_rec[kw_hdr->keywords_count-1].name_offset;
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi buf = buffer_create_dynamic(pool_datastack_create(), 512);
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi buffer_append(buf, &new_kw_hdr, sizeof(new_kw_hdr));
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi buffer_append(buf, kw_rec, sizeof(*kw_rec) * kw_hdr->keywords_count);
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi buffer_write(buf, buf->used + sizeof(*kw_rec) * new_count,
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumistatic int keywords_ext_register(struct mail_index_sync_map_ctx *ctx,
8adef7614d4340b4ee44a4441fadd530f48515edKATOH Yasufumi buffer_create_static_hard(pool_datastack_create(),
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi u = buffer_append_space_unsafe(ext_intro_buf, sizeof(*u));
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi u->record_size = (keywords_count + CHAR_BIT - 1) / CHAR_BIT;
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi /* since we aren't properly aligned anyway,
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi reserve one extra byte for future */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi buffer_append(ext_intro_buf, "keywords", u->name_size);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumikeywords_header_add(struct mail_index_sync_map_ctx *ctx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const char *keyword_name, unsigned int *keyword_idx_r)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi size_t keyword_len, rec_offset, name_offset, name_offset_root;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ext_id = mail_index_map_lookup_ext(map, "keywords");
d0348408b5fa226bf7f8031c6abf2d5d2a28ba33TAMUKI Shoichi /* update existing header */
d0348408b5fa226bf7f8031c6abf2d5d2a28ba33TAMUKI Shoichi buf = keywords_get_header_buf(map, ext, 1, &keywords_count,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* create new / replace broken header */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi buf = buffer_create_dynamic(pool_datastack_create(), 512);
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi kw_hdr = buffer_append_space_unsafe(buf, sizeof(*kw_hdr));
ffeb76b4607be4b241db01ab65989d37b4529c97TAMUKI Shoichi /* add the keyword */
ea00a202cde59a23daba00b64ec92fb9a748327aTAMUKI Shoichi buffer_write(buf, rec_offset, &kw_rec, sizeof(kw_rec));
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi buffer_write(buf, name_offset_root, keyword_name, keyword_len);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi buffer_append_zero(buf, 4 - (buf->used % 4));
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (ext == NULL || buf->used > ext->hdr_size ||
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi (uint32_t)ext->record_size * CHAR_BIT < keywords_count) {
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* if we need to grow the buffer, add some padding */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* map may have changed */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ext_id = mail_index_map_lookup_ext(map, "keywords");
db821c3a4168c9c1072a433340e6009892e26cf2KATOH Yasufumi buffer_copy(map->hdr_copy_buf, ext->hdr_offset,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumikeywords_update_records(struct mail_index_view *view,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (mail_index_lookup_uid_range(view, uid1, uid2, &seq1, &seq2) < 0)
d0348408b5fa226bf7f8031c6abf2d5d2a28ba33TAMUKI Shoichiint mail_index_sync_keywords(struct mail_index_sync_map_ctx *ctx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const struct mail_transaction_keyword_update *rec)
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi seqset_offset = sizeof(*rec) + rec->name_size;
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi mail_transaction_log_view_set_corrupted(ctx->view->log_view,
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi "Keyword header ended unexpectedly");
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi mail_transaction_log_view_set_corrupted(ctx->view->log_view,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi "Keyword sequence list empty");
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi keyword_name = t_strndup(rec + 1, rec->name_size);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (keyword_lookup(ctx, keyword_name, &keyword_idx) < 0)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ret = keywords_header_add(ctx, keyword_name, &keyword_idx);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ext_id = mail_index_map_lookup_ext(ctx->view->map, "keywords");
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* nothing to do */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ext = array_idx(&ctx->view->map->extensions, ext_id);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* nothing to do */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (mail_index_map_read_keywords(ctx->view->index,
ffeb76b4607be4b241db01ab65989d37b4529c97TAMUKI Shoichi "Keyword record UIDs are broken");
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ret = keywords_update_records(ctx->view, ext, keyword_idx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumimail_index_sync_keywords_reset(struct mail_index_sync_map_ctx *ctx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const struct mail_transaction_keyword_reset *r)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const struct mail_transaction_keyword_reset *end;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ext_id = mail_index_map_lookup_ext(map, "keywords");
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* nothing to do */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi for (; r != end; r++) {