Cross Reference: /dovecot/src/plugins/fts/fts-storage.c
fts-storage.c revision 7c311effa7150d364232e6f2d0a1fa623dbb8d95
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen/* Copyright (C) 2006 Timo Sirainen */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "str.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "istream.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "message-parser.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "message-decoder.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-search.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-storage-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-api-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-plugin.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include <stdlib.h>
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#define FTS_CONTEXT(obj) \
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen *((void **)array_idx_modifiable(&(obj)->module_contexts, \
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fts_storage_module_id))
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstruct fts_mailbox {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mailbox_vfuncs super;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_backend *backend;
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen const char *env;
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen unsigned int backend_failed:1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen};
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstruct fts_search_context {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) result;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int result_pos;
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen unsigned int locked:1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen};
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstruct fts_transaction_context {
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen bool expunges;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen};
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenstruct fts_mail {
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct mail_vfuncs super;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen};
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic unsigned int fts_storage_module_id = 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic bool fts_storage_module_id_set = FALSE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_mailbox_close(struct mailbox *box)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen int ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen if (fbox->backend != NULL)
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fts_backend_deinit(fbox->backend);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen ret = fbox->super.close(box);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen i_free(fbox);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int uid_range_to_seq(struct mailbox *box,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) *uid_range,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) *seq_range)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct seq_range *range;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct seq_range new_range;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen range = array_get(uid_range, &count);
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen i_array_init(seq_range, count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < count; i++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mailbox_get_uids(box, range[i].seq1, range[i].seq2,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen &new_range.seq1, &new_range.seq2) < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(seq_range);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (new_range.seq1 != 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_append(seq_range, &new_range, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstruct fts_storage_build_context {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_backend_build_context *build;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t uid;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen string_t *headers;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen bool save_part;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen};
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenstatic int fts_build_mail_flush(struct fts_storage_build_context *ctx)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen{
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (str_len(ctx->headers) == 0)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return 1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (fts_backend_build_more(ctx->build, ctx->uid, str_data(ctx->headers),
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen str_len(ctx->headers)) < 0)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return -1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen str_truncate(ctx->headers, 0);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return 1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen}
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenstatic bool fts_build_update_save_part(struct fts_storage_build_context *ctx,
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen const struct message_block *block)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen{
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen /* we'll index only text/xxx and message/rfc822 parts for now */
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if ((block->part->flags &
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen (MESSAGE_PART_FLAG_TEXT |
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return FALSE;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen ctx->save_part = TRUE;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return TRUE;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen}
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_build_mail_header(struct fts_storage_build_context *ctx,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct message_block *block)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct message_header_line *hdr = block->hdr;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* hdr->full_value is always set because we get the block from
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen message_decoder */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_append(ctx->headers, hdr->name);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_append_n(ctx->headers, hdr->middle, hdr->middle_len);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_append_n(ctx->headers, hdr->full_value, hdr->full_value_len);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!hdr->no_newline)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_append_c(ctx->headers, '\n');
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!ctx->save_part) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (strcasecmp(hdr->name, "Content-Type") == 0) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (!fts_build_update_save_part(ctx, block))
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return fts_build_mail_flush(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenfts_build_mail(struct fts_storage_build_context *ctx, struct mail *mail)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct istream *input;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct message_parser_ctx *parser;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct message_decoder_context *decoder;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct message_block raw_block, block;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct message_part *prev_part, *skip_part;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen int ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->uid = mail->uid;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen input = mail_get_stream(mail, NULL, NULL);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (input == NULL)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen prev_part = skip_part = NULL;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen parser = message_parser_init(pool_datastack_create(), input);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen decoder = message_decoder_init();
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (;;) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = message_parser_parse_next_block(parser, &raw_block);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_assert(ret != 0);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ret < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (input->stream_errno == 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (raw_block.part == skip_part)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen continue;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!message_decoder_decode_next_block(decoder, &raw_block,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen &block))
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen continue;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (block.part != prev_part &&
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen (block.hdr != NULL || block.size != 0)) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen str_truncate(ctx->headers, 0);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen ctx->save_part = FALSE;
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen prev_part = block.part;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen skip_part = NULL;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (block.hdr != NULL) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = fts_build_mail_header(ctx, &block);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ret < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ret == 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen skip_part = raw_block.part;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen } else if (block.size == 0) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen /* end of headers */
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (fts_build_update_save_part(ctx, &block)) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen ret = fts_build_mail_flush(ctx);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (ret < 0)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen break;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen } else {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_backend_build_more(ctx->build, mail->uid,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen block.data,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen block.size) < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen (void)message_parser_deinit(&parser);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen message_decoder_deinit(&decoder);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_build_new(struct mailbox_transaction_context *t)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_storage_build_context ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_search_context *search_ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_search_seqset seqset;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_search_arg search_arg;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail *mail;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen uint32_t last_uid, last_uid_locked;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen int ret = 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen if (fts_backend_get_last_uid(fbox->backend, &last_uid) < 0)
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen return -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen memset(&seqset, 0, sizeof(seqset));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mailbox_get_uids(t->box, last_uid+1, (uint32_t)-1,
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen &seqset.seq1, &seqset.seq2) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (seqset.seq1 == 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* no new messages */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen memset(&ctx, 0, sizeof(ctx));
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen ctx.build = fts_backend_build_init(fbox->backend, &last_uid_locked);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen if (last_uid != last_uid_locked) {
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen /* changed, need to get again the sequences */
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen i_assert(last_uid < last_uid_locked);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen last_uid = last_uid_locked;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen if (mailbox_get_uids(t->box, last_uid+1, (uint32_t)-1,
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen &seqset.seq1, &seqset.seq2) < 0) {
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen (void)fts_backend_build_deinit(ctx.build);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen return -1;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen }
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen if (seqset.seq1 == 0) {
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen /* no new messages */
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen (void)fts_backend_build_deinit(ctx.build);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen return 0;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen }
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen }
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen memset(&search_arg, 0, sizeof(search_arg));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen search_arg.type = SEARCH_SEQSET;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen search_arg.value.seqset = &seqset;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx.headers = str_new(default_pool, 512);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail = mail_alloc(t, 0, NULL);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen search_ctx = mailbox_search_init(t, NULL, &search_arg, NULL);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen while (mailbox_search_next(search_ctx, mail) > 0) {
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen t_push();
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen ret = fts_build_mail(&ctx, mail);
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen t_pop();
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen if (ret < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mailbox_search_deinit(&search_ctx) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_free(&mail);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_backend_build_deinit(ctx.build) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret = -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_free(&ctx.headers);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic struct mail_search_context *
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenfts_mailbox_search_init(struct mailbox_transaction_context *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const char *charset, struct mail_search_arg *args,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const enum mail_sort_type *sort_program)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_search_context *ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_search_context *fctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) uid_result;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx = fbox->super.search_init(t, charset, args, sort_program);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fctx = i_new(struct fts_search_context, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_idx_set(&ctx->module_contexts, fts_storage_module_id, &fctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen if (fbox->backend == NULL)
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen return ctx;
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* FIXME: handle AND/OR. Maybe also header lookups? */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen while (args != NULL &&
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args->type != SEARCH_BODY &&
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args->type != SEARCH_TEXT)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args = args->next;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (args != NULL) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_build_new(t) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen if (fts_backend_lock(fbox->backend) <= 0)
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen return ctx;
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen fctx->locked = TRUE;
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen i_array_init(&uid_result, 64);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_backend_lookup(fbox->backend, args->value.str,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen &uid_result) < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* failed, fallback to reading everything */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&uid_result);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen if (fbox->backend->definite_lookups) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen args->match_always = TRUE;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen args->result = 1;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args = args->next;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen while (args != NULL) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (args->type == SEARCH_BODY ||
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args->type == SEARCH_TEXT) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen if (fbox->backend->definite_lookups) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen args->match_always = TRUE;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen args->result = 1;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_backend_filter(fbox->backend,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args->value.str,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen &uid_result) < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* failed, but we already have limited
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen the search, so just ignore this */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen args = args->next;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (array_is_created(&uid_result)) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen (void)uid_range_to_seq(t->box, &uid_result,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen &fctx->result);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&uid_result);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_mailbox_search_next_update_seq(struct mail_search_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct seq_range *range;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int count;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen uint32_t wanted_seq;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen int ret;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen if (!array_is_created(&fctx->result))
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen return fbox->super.search_next_update_seq(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen do {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen range = array_get_modifiable(&fctx->result, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen while (fctx->result_pos < count &&
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->seq > range[fctx->result_pos].seq2)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fctx->result_pos++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fctx->result_pos == count)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ctx->seq > range[fctx->result_pos].seq1)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen range[fctx->result_pos].seq1 = ctx->seq+1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen else {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->seq = range[fctx->result_pos].seq1 - 1;
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen if (fctx->result_pos < count &&
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen ctx->seq + 1 == range[fctx->result_pos].seq2)
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen fctx->result_pos++;
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen else
4bffa20ff6fc61ba7b47375722e38be7f87dfe64Timo Sirainen range[fctx->result_pos].seq1++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen wanted_seq = ctx->seq + 1;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen ret = fbox->super.search_next_update_seq(ctx);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen } while (ret > 0 && wanted_seq != ctx->seq);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_mailbox_search_deinit(struct mail_search_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen if (fctx->locked)
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen fts_backend_unlock(fbox->backend);
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (array_is_created(&fctx->result))
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&fctx->result);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_free(fctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return fbox->super.search_deinit(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenstatic int fts_mail_expunge(struct mail *_mail)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen{
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct fts_mail *fmail = FTS_CONTEXT(mail);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(_mail->box);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen if (fmail->super.expunge(_mail) < 0)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen return -1;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen ft->expunges = TRUE;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen fts_backend_expunge(fbox->backend, _mail);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen return 0;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen}
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenstatic struct mail *
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenfts_mail_alloc(struct mailbox_transaction_context *t,
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen enum mail_fetch_field wanted_fields,
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen{
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct fts_mail *fmail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct mail *_mail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen struct mail_private *mail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen _mail = fbox->super.mail_alloc(t, wanted_fields, wanted_headers);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen if (fbox->backend != NULL) {
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen mail = (struct mail_private *)_mail;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fmail = p_new(mail->pool, struct fts_mail, 1);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fmail->super = mail->v;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen mail->v.expunge = fts_mail_expunge;
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen array_idx_set(&mail->module_contexts,
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fts_storage_module_id, &fmail);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen }
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen return _mail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen}
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic struct mailbox_transaction_context *
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenfts_transaction_begin(struct mailbox *box,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen enum mailbox_transaction_flags flags)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct mailbox_transaction_context *t;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen ft = i_new(struct fts_transaction_context, 1);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen /* the backend creation is delayed until the first transaction is
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen started. at that point the mailbox has been synced at least once. */
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen if (fbox->backend == NULL && !fbox->backend_failed) {
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fbox->backend = fts_backend_init(fbox->env, box);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen if (fbox->backend == NULL)
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fbox->backend_failed = TRUE;
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen }
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen t = fbox->super.transaction_begin(box, flags);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen array_idx_set(&t->module_contexts, fts_storage_module_id, &ft);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return t;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic void fts_transaction_rollback(struct mailbox_transaction_context *t)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct mailbox *box = t->box;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen fbox->super.transaction_rollback(t);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (ft->expunges)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen fts_backend_expunge_finish(fbox->backend, box, FALSE);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen i_free(ft);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic int fts_transaction_commit(struct mailbox_transaction_context *t,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen enum mailbox_sync_flags flags)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct mailbox *box = t->box;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen int ret;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen ret = fbox->super.transaction_commit(t, flags);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (ft->expunges)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen fts_backend_expunge_finish(fbox->backend, box, ret == 0);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen i_free(ft);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return ret;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_mailbox_opened(struct mailbox *box)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox;
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen const char *env;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (fts_next_hook_mailbox_opened != NULL)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fts_next_hook_mailbox_opened(box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen env = getenv("FTS");
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (env == NULL)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fbox = i_new(struct fts_mailbox, 1);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen fbox->env = env;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fbox->super = box->v;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen box->v.close = fts_mailbox_close;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen box->v.search_init = fts_mailbox_search_init;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen box->v.search_next_update_seq = fts_mailbox_search_next_update_seq;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen box->v.search_deinit = fts_mailbox_search_deinit;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen box->v.mail_alloc = fts_mail_alloc;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen box->v.transaction_begin = fts_transaction_begin;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen box->v.transaction_rollback = fts_transaction_rollback;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen box->v.transaction_commit = fts_transaction_commit;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!fts_storage_module_id_set) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fts_storage_module_id = mail_storage_module_id++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen fts_storage_module_id_set = TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_idx_set(&box->module_contexts, fts_storage_module_id, &fbox);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}