1 /* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "array.h"
5 #include "http-client.h"
6 #include "mail-user.h"
7 #include "mail-storage-hooks.h"
8 #include "solr-connection.h"
9 #include "fts-user.h"
10 #include "fts-solr-plugin.h"
11
12 #define DEFAULT_SOLR_BATCH_SIZE 1000
13
14 const char *fts_solr_plugin_version = DOVECOT_ABI_VERSION;
15 struct http_client *solr_http_client = NULL;
16
17 struct fts_solr_user_module fts_solr_user_module =
18 MODULE_CONTEXT_INIT(&mail_user_module_register);
19
20 static int
fts_solr_plugin_init_settings(struct mail_user * user,struct fts_solr_settings * set,const char * str)21 fts_solr_plugin_init_settings(struct mail_user *user,
22 struct fts_solr_settings *set, const char *str)
23 {
24 const char *const *tmp;
25
26 if (str == NULL)
27 str = "";
28
29 set->batch_size = DEFAULT_SOLR_BATCH_SIZE;
30 set->soft_commit = TRUE;
31
32 for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) {
33 if (str_begins(*tmp, "url=")) {
34 set->url = p_strdup(user->pool, *tmp + 4);
35 } else if (strcmp(*tmp, "debug") == 0) {
36 set->debug = TRUE;
37 } else if (strcmp(*tmp, "use_libfts") == 0) {
38 set->use_libfts = TRUE;
39 } else if (str_begins(*tmp, "default_ns=")) {
40 set->default_ns_prefix =
41 p_strdup(user->pool, *tmp + 11);
42 } else if (str_begins(*tmp, "rawlog_dir=")) {
43 set->rawlog_dir = p_strdup(user->pool, *tmp + 11);
44 } else if (str_begins(*tmp, "batch_size=")) {
45 if (str_to_uint(*tmp+11, &set->batch_size) < 0 ||
46 set->batch_size == 0) {
47 i_error("fts_solr: batch_size must be a positive integer");
48 return -1;
49 }
50 } else if (str_begins(*tmp, "soft_commit=")) {
51 if (strcmp(*tmp + 12, "yes") == 0) {
52 set->soft_commit = TRUE;
53 } else if (strcmp(*tmp + 12, "no") == 0) {
54 set->soft_commit = FALSE;
55 } else {
56 i_error("fts_solr: Invalid setting for soft_commit: %s", *tmp+12);
57 return -1;
58 }
59 } else {
60 i_error("fts_solr: Invalid setting: %s", *tmp);
61 return -1;
62 }
63 }
64 if (set->url == NULL) {
65 i_error("fts_solr: url setting missing");
66 return -1;
67 }
68 return 0;
69 }
70
fts_solr_mail_user_deinit(struct mail_user * user)71 static void fts_solr_mail_user_deinit(struct mail_user *user)
72 {
73 struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT_REQUIRE(user);
74
75 fts_mail_user_deinit(user);
76 fuser->module_ctx.super.deinit(user);
77 }
78
fts_solr_mail_user_create(struct mail_user * user,const char * env)79 static void fts_solr_mail_user_create(struct mail_user *user, const char *env)
80 {
81 struct mail_user_vfuncs *v = user->vlast;
82 struct fts_solr_user *fuser;
83 const char *error;
84
85 fuser = p_new(user->pool, struct fts_solr_user, 1);
86 if (fts_solr_plugin_init_settings(user, &fuser->set, env) < 0) {
87 /* invalid settings, disabling */
88 return;
89 }
90 if (fts_mail_user_init(user, fuser->set.use_libfts, &error) < 0) {
91 i_error("fts-solr: %s", error);
92 return;
93 }
94
95 fuser->module_ctx.super = *v;
96 user->vlast = &fuser->module_ctx.super;
97 v->deinit = fts_solr_mail_user_deinit;
98 MODULE_CONTEXT_SET(user, fts_solr_user_module, fuser);
99 }
100
fts_solr_mail_user_created(struct mail_user * user)101 static void fts_solr_mail_user_created(struct mail_user *user)
102 {
103 const char *env;
104
105 env = mail_user_plugin_getenv(user, "fts_solr");
106 if (env != NULL)
107 fts_solr_mail_user_create(user, env);
108 }
109
110 static struct mail_storage_hooks fts_solr_mail_storage_hooks = {
111 .mail_user_created = fts_solr_mail_user_created
112 };
113
fts_solr_plugin_init(struct module * module)114 void fts_solr_plugin_init(struct module *module)
115 {
116 fts_backend_register(&fts_backend_solr);
117 fts_backend_register(&fts_backend_solr_old);
118 mail_storage_hooks_add(module, &fts_solr_mail_storage_hooks);
119 }
120
fts_solr_plugin_deinit(void)121 void fts_solr_plugin_deinit(void)
122 {
123 fts_backend_unregister(fts_backend_solr.name);
124 fts_backend_unregister(fts_backend_solr_old.name);
125 mail_storage_hooks_remove(&fts_solr_mail_storage_hooks);
126 if (solr_http_client != NULL)
127 http_client_deinit(&solr_http_client);
128
129 }
130
131 const char *fts_solr_plugin_dependencies[] = { "fts", NULL };
132