mail-index-sync-keywords.c revision faed8babca9914257f34fb2e603d74016d563b2d
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenkeyword_lookup(struct mail_index_sync_map_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *keyword_name, unsigned int *idx_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map_read_keywords(ctx->view->index, map) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strcmp(map->keywords[i], keyword_name) == 0) {
ad850190d946d34966a56838cfdb216e021b5b5fTimo Sirainenkeywords_get_header_buf(struct mail_index_map *map,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int new_count, unsigned int *keywords_count_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t *rec_offset_r, size_t *name_offset_root_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_keyword_header *kw_hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_keyword_header_rec *kw_rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen name = (const char *)(kw_rec + kw_hdr->keywords_count);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *keywords_count_r = new_kw_hdr.keywords_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen offset = kw_rec[kw_hdr->keywords_count-1].name_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 512);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(buf, &new_kw_hdr, sizeof(new_kw_hdr));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(buf, kw_rec, sizeof(*kw_rec) * kw_hdr->keywords_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_write(buf, buf->used + sizeof(*kw_rec) * new_count,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenstatic int keywords_ext_register(struct mail_index_sync_map_ctx *ctx,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen buffer_create_static_hard(pool_datastack_create(),
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen u = buffer_append_space_unsafe(ext_intro_buf, sizeof(*u));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen u->record_size = (keywords_count + CHAR_BIT - 1) / CHAR_BIT;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* since we aren't properly aligned anyway,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen reserve one extra byte for future */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen buffer_append(ext_intro_buf, "keywords", u->name_size);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenkeywords_header_add(struct mail_index_sync_map_ctx *ctx,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const char *keyword_name, unsigned int *keyword_idx_r)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen size_t keyword_len, rec_offset, name_offset, name_offset_root;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ext_id = mail_index_map_lookup_ext(map, "keywords");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* update existing header */
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen buf = keywords_get_header_buf(map, ext, 1, &keywords_count,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* create new / replace broken header */
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 512);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen kw_hdr = buffer_append_space_unsafe(buf, sizeof(*kw_hdr));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* add the keyword */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_write(buf, rec_offset, &kw_rec, sizeof(kw_rec));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen buffer_write(buf, name_offset_root, keyword_name, keyword_len);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ext == NULL || buf->used > ext->hdr_size ||
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen (uint32_t)ext->record_size * CHAR_BIT < keywords_count) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* if we need to grow the buffer, add some padding */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* map may have changed */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen ext_id = mail_index_map_lookup_ext(map, "keywords");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen buffer_copy(map->hdr_copy_buf, ext->hdr_offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenkeywords_update_records(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup_uid_range(view, uid1, uid2, &seq1, &seq2) < 0)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenint mail_index_sync_keywords(struct mail_index_sync_map_ctx *ctx,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const struct mail_transaction_keyword_update *rec)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seqset_offset = sizeof(*rec) + rec->name_size;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen "Keyword header ended unexpectedly");
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen "Keyword sequence list empty");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen keyword_name = t_strndup(rec + 1, rec->name_size);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (keyword_lookup(ctx, keyword_name, &keyword_idx) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ret = keywords_header_add(ctx, keyword_name, &keyword_idx);
69bd816e46fdee6182d0cb2e4c6be32399a555c8Timo Sirainen ext_id = mail_index_map_lookup_ext(ctx->view->map, "keywords");
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen /* nothing to do */
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen /* nothing to do */
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (mail_index_map_read_keywords(ctx->view->index,
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen "Keyword record UIDs are broken");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = keywords_update_records(ctx->view, ext, keyword_idx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_sync_keywords_reset(struct mail_index_sync_map_ctx *ctx,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const struct mail_transaction_keyword_reset *r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_keyword_reset *end;
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen ext_id = mail_index_map_lookup_ext(map, "keywords");
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen /* nothing to do */
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen for (; r != end; r++) {