bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "hex-binary.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "mail-index.h"
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen#include "mail-namespace.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "mail-storage-private.h"
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen#include "mailbox-list-iter.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "mail-search.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-api-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic ARRAY(const struct fts_backend *) backends;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_backend_register(const struct fts_backend *backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen if (!array_is_created(&backends))
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen i_array_init(&backends, 4);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_append(&backends, &backend, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_backend_unregister(const char *name)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct fts_backend *const *be;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen be = array_get(&backends, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < count; i++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (strcmp(be[i]->name, name) == 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_delete(&backends, i, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (i == count)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_panic("fts_backend_unregister(%s): unknown backend", name);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (count == 1)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&backends);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenstatic const struct fts_backend *
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenfts_backend_class_lookup(const char *backend_name)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct fts_backend *const *be;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen if (array_is_created(&backends)) {
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen be = array_get(&backends, &count);
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen for (i = 0; i < count; i++) {
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen if (strcmp(be[i]->name, backend_name) == 0)
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen return be[i];
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return NULL;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_init(const char *backend_name, struct mail_namespace *ns,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char **error_r, struct fts_backend **backend_r)
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen{
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen const struct fts_backend *be;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen struct fts_backend *backend;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen be = fts_backend_class_lookup(backend_name);
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen if (be == NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *error_r = "Unknown backend";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen }
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend = be->v.alloc();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->ns = ns;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (backend->v.init(backend, error_r) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_free(backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *backend_r = backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen}
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid fts_backend_deinit(struct fts_backend **_backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct fts_backend *backend = *_backend;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen *_backend = NULL;
e80307fd7345f60540c7d83c38952603d2df9e9bTimo Sirainen backend->v.deinit(backend);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_get_last_uid(struct fts_backend *backend, struct mailbox *box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t *last_uid_r)
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen{
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen struct fts_index_header hdr;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen if (box->virtual_vfuncs != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* virtual mailboxes themselves don't have any indexes,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen so catch this call here */
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen if (!fts_index_get_header(box, &hdr))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *last_uid_r = 0;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen else
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen *last_uid_r = hdr.last_indexed_uid;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return backend->v.get_last_uid(backend, box, last_uid_r);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen}
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_is_updating(struct fts_backend *backend)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return backend->updating;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct fts_backend_update_context *
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_update_init(struct fts_backend *backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen struct fts_backend_update_context *ctx;
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(!backend->updating);
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->updating = TRUE;
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen ctx = backend->v.update_init(backend);
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen if ((backend->flags & FTS_BACKEND_FLAG_NORMALIZE_INPUT) != 0)
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen ctx->normalizer = backend->ns->user->default_normalizer;
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen return ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_backend_set_cur_mailbox(struct fts_backend_update_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_update_unset_build_key(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->backend_box != ctx->cur_box) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_set_mailbox(ctx, ctx->cur_box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend_box = ctx->cur_box;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_update_deinit(struct fts_backend_update_context **_ctx)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend_update_context *ctx = *_ctx;
cea6742c34fcf3f62c30aab4d2120a689d5b1844Timo Sirainen struct fts_backend *backend = ctx->backend;
cea6742c34fcf3f62c30aab4d2120a689d5b1844Timo Sirainen int ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *_ctx = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->cur_box = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_set_cur_mailbox(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
cea6742c34fcf3f62c30aab4d2120a689d5b1844Timo Sirainen ret = backend->v.update_deinit(ctx);
cea6742c34fcf3f62c30aab4d2120a689d5b1844Timo Sirainen backend->updating = FALSE;
cea6742c34fcf3f62c30aab4d2120a689d5b1844Timo Sirainen return ret;
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_set_mailbox(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->backend_box != NULL && box != ctx->backend_box) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* make sure we don't reference the backend box anymore */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_set_mailbox(ctx, NULL);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend_box = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->cur_box = box;
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_expunge(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t uid)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_set_cur_mailbox(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_expunge(ctx, uid);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_update_set_build_key(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct fts_backend_build_key *key)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_set_cur_mailbox(ctx);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen i_assert(ctx->cur_box != NULL);
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!ctx->backend->v.update_set_build_key(ctx, key))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->build_key_open = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_unset_build_key(struct fts_backend_update_context *ctx)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->build_key_open) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_unset_build_key(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->build_key_open = FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen}
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_update_build_more(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const unsigned char *data, size_t size)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(ctx->build_key_open);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ctx->backend->v.update_build_more(ctx, data, size);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainenint fts_backend_refresh(struct fts_backend *backend)
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen{
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainen return backend->v.refresh(backend);
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen}
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainenint fts_backend_reset_last_uids(struct fts_backend *backend)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen{
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen struct mailbox_list_iterate_context *iter;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen const struct mailbox_info *info;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen struct mailbox *box;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen int ret = 0;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen iter = mailbox_list_iter_init(backend->ns->list, "*",
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen MAILBOX_LIST_ITER_SKIP_ALIASES |
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES);
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen if ((info->flags &
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) != 0)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen continue;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen box = mailbox_alloc(info->ns->list, info->vname, 0);
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen if (mailbox_open(box) == 0) {
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen if (fts_index_set_last_uid(box, 0) < 0)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen ret = -1;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen }
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen mailbox_free(&box);
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen }
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen if (mailbox_list_iter_deinit(&iter) < 0)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen ret = -1;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen return ret;
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen}
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainenint fts_backend_rescan(struct fts_backend *backend)
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen{
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen struct mailbox *box;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen bool virtual_storage;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen box = mailbox_alloc(backend->ns->list, "", 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen virtual_storage = box->virtual_vfuncs != NULL;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen mailbox_free(&box);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen if (virtual_storage) {
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen /* just reset the last-uids for a virtual storage. */
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen return fts_backend_reset_last_uids(backend);
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen }
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen return backend->v.rescan == NULL ? 0 :
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen backend->v.rescan(backend);
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen}
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_optimize(struct fts_backend *backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return backend->v.optimize == NULL ? 0 :
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->v.optimize(backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstatic void
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenfts_merge_maybies(ARRAY_TYPE(seq_range) *dest_maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *dest_definite,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *src_maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *src_definite)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen ARRAY_TYPE(seq_range) src_unwanted;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen const struct seq_range *range;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen struct seq_range new_range;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen unsigned int i, count;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen uint32_t seq;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* add/leave to dest_maybe if at least one list has maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen and no lists have none */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* create unwanted sequences list from both sources */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen t_array_init(&src_unwanted, 128);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen new_range.seq1 = 0; new_range.seq2 = (uint32_t)-1;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen array_append(&src_unwanted, &new_range, 1);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_maybe);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_definite);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* drop unwanted uids */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(dest_maybe, &src_unwanted);
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* add uids that are in dest_definite and src_maybe lists */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen range = array_get(dest_definite, &count);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (i = 0; i < count; i++) {
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (seq = range[i].seq1; seq <= range[i].seq2; seq++) {
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen if (seq_range_exists(src_maybe, seq))
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen seq_range_array_add(dest_maybe, seq);
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen }
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenvoid fts_filter_uids(ARRAY_TYPE(seq_range) *definite_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const ARRAY_TYPE(seq_range) *definite_filter,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *maybe_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const ARRAY_TYPE(seq_range) *maybe_filter)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen T_BEGIN {
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fts_merge_maybies(maybe_dest, definite_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybe_filter, definite_filter);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen } T_END;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen /* keep only what exists in both lists. the rest is in
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybies or not wanted */
809923ba26218971792182ae8894936f9ac99364Timo Sirainen seq_range_array_intersect(definite_dest, definite_filter);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_default_can_lookup(struct fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *args)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; args != NULL; args = args->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (args->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SUB:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_default_can_lookup(backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen args->value.subargs))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_ADDRESS:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_BODY:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_TEXT:
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang if (!args->no_fts)
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang return TRUE;
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen default:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_can_lookup(struct fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *args)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return backend->v.can_lookup(backend, args);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int fts_score_map_sort(const struct fts_score_map *m1,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct fts_score_map *m2)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (m1->uid < m2->uid)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (m1->uid > m2->uid)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 1;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return 0;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_lookup(struct fts_backend *backend, struct mailbox *box,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen struct mail_search_arg *args,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen enum fts_lookup_flags flags,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_result *result)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&result->definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&result->maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&result->scores);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen if (backend->v.lookup(backend, box, args, flags, result) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!result->scores_sorted && array_is_created(&result->scores)) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_sort(&result->scores, fts_score_map_sort);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen result->scores_sorted = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_lookup_multi(struct fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *const boxes[],
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen struct mail_search_arg *args,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen enum fts_lookup_flags flags,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_multi_result *result)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen unsigned int i;
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(boxes[0] != NULL);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen if (backend->v.lookup_multi != NULL) {
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen if (backend->v.lookup_multi(backend, boxes, args,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen flags, result) < 0)
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen return -1;
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen if (result->box_results == NULL) {
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen result->box_results = p_new(result->pool,
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen struct fts_result, 1);
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen }
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen return 0;
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen }
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen for (i = 0; boxes[i] != NULL; i++) ;
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen result->box_results = p_new(result->pool, struct fts_result, i+1);
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen for (i = 0; boxes[i] != NULL; i++) {
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen struct fts_result *box_result = &result->box_results[i];
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->definite_uids, result->pool, 32);
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->maybe_uids, result->pool, 32);
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->scores, result->pool, 32);
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen if (backend->v.lookup(backend, boxes[i], args,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen flags, box_result) < 0)
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen return -1;
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen }
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen return 0;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainenvoid fts_backend_lookup_done(struct fts_backend *backend)
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen{
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen if (backend->v.lookup_done != NULL)
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen backend->v.lookup_done(backend);
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen}
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenstatic uint32_t fts_index_get_ext_id(struct mailbox *box)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen{
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen return mail_index_ext_register(box->index, "fts",
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen sizeof(struct fts_index_header),
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen 0, 0);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen}
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenbool fts_index_get_header(struct mailbox *box, struct fts_index_header *hdr_r)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen struct mail_index_view *view;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const void *data;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen size_t data_size;
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen bool ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen mail_index_refresh(box->index);
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen view = mail_index_view_open(box->index);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen mail_index_get_header_ext(view, fts_index_get_ext_id(box),
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen &data, &data_size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (data_size < sizeof(*hdr_r)) {
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(hdr_r);
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen ret = FALSE;
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen } else {
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen memcpy(hdr_r, data, data_size);
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen ret = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen mail_index_view_close(&view);
403762eeaebbedce130b1cec435441b22ee8f349Timo Sirainen return ret;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenint fts_index_set_header(struct mailbox *box,
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen const struct fts_index_header *hdr)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen struct mail_index_transaction *trans;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen uint32_t ext_id = fts_index_get_ext_id(box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen trans = mail_index_transaction_begin(box->view, 0);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen mail_index_update_header_ext(trans, ext_id, 0, hdr, sizeof(*hdr));
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen return mail_index_transaction_commit(&trans);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_index_set_last_uid(struct mailbox *box, uint32_t last_uid)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_index_header hdr;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen (void)fts_index_get_header(box, &hdr);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen hdr.last_indexed_uid = last_uid;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen return fts_index_set_header(box, &hdr);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen}
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenint fts_index_have_compatible_settings(struct mailbox_list *list,
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen uint32_t checksum)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen{
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen struct mail_namespace *ns = mailbox_list_get_namespace(list);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen struct mailbox *box;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen struct fts_index_header hdr;
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen const char *vname;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t len;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen int ret;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0)
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen vname = "INBOX";
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen else {
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen len = strlen(ns->prefix);
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen len--;
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen vname = t_strndup(ns->prefix, len);
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen }
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen box = mailbox_alloc(list, vname, 0);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen if (mailbox_sync(box, (enum mailbox_sync_flags)0) < 0) {
b8673ed3de3d1931ea5319c7557b72235cfe31feTimo Sirainen i_error("fts: Failed to sync mailbox %s: %s", vname,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen ret = -1;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen } else {
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen ret = fts_index_get_header(box, &hdr) &&
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen hdr.settings_checksum == checksum ? 1 : 0;
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen }
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen mailbox_free(&box);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen return ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic const char *indexed_headers[] = {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "From", "To", "Cc", "Bcc", "Subject"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_header_want_indexed(const char *hdr_name)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int i;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (i = 0; i < N_ELEMENTS(indexed_headers); i++) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (strcasecmp(hdr_name, indexed_headers[i]) == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainenbool fts_header_has_language(const char *hdr_name)
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen{
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen /* FIXME: should email address headers be detected as different
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen languages? That mainly contains people's names.. */
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen /*if (message_header_is_address(hdr_name))
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen return TRUE;*/
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen /* Subject definitely contains language-specific data that can be
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen detected. Comment and Keywords headers also could contain, although
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen just about nobody uses those headers.
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen For now we assume that other headers contain non-language specific
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen data that we don't want to filter in special ways. For example
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen it is good to be able to search for Message-IDs. */
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen return strcasecmp(hdr_name, "Subject") == 0 ||
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen strcasecmp(hdr_name, "Comments") == 0 ||
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen strcasecmp(hdr_name, "Keywords") == 0;
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen}
4ac43ad128cb9b22f1c936659a1ff62e5b6c8bc3Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_mailbox_get_guid(struct mailbox *box, const char **guid_r)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox_metadata metadata;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen *guid_r = guid_128_to_string(metadata.guid);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}