~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/imap/imap-search.c

  • Committer: Package Import Robot
  • Author(s): Jaldhar H. Vyas
  • Date: 2013-09-09 00:57:32 UTC
  • mfrom: (1.13.11)
  • mto: (4.8.5 experimental) (1.16.1)
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: package-import@ubuntu.com-20130909005732-dn1eell8srqbhh0e
Tags: upstream-2.2.5
ImportĀ upstreamĀ versionĀ 2.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "imap-common.h"
4
4
#include "ostream.h"
10
10
#include "imap-seqset.h"
11
11
#include "imap-util.h"
12
12
#include "mail-search-build.h"
 
13
#include "imap-fetch.h"
13
14
#include "imap-commands.h"
14
15
#include "imap-search-args.h"
15
16
#include "imap-search.h"
42
43
}
43
44
 
44
45
static bool
 
46
search_parse_fetch_att(struct imap_search_context *ctx,
 
47
                       const struct imap_arg *update_args)
 
48
{
 
49
        const char *error;
 
50
 
 
51
        ctx->fetch_pool = pool_alloconly_create("search update fetch", 512);
 
52
        if (imap_fetch_att_list_parse(ctx->cmd->client, ctx->fetch_pool,
 
53
                                      update_args, &ctx->fetch_ctx, &error) < 0) {
 
54
                client_send_command_error(ctx->cmd, t_strconcat(
 
55
                        "SEARCH UPDATE fetch-att: ", error, NULL));
 
56
                pool_unref(&ctx->fetch_pool);
 
57
                return FALSE;
 
58
        }
 
59
        return TRUE;
 
60
}
 
61
 
 
62
static bool
45
63
search_parse_return_options(struct imap_search_context *ctx,
46
64
                            const struct imap_arg *args)
47
65
{
48
66
        struct client_command_context *cmd = ctx->cmd;
 
67
        const struct imap_arg *update_args;
49
68
        const char *name, *str;
50
69
        unsigned int idx;
51
70
 
69
88
                        ctx->return_options |= SEARCH_RETURN_SAVE;
70
89
                else if (strcmp(name, "CONTEXT") == 0) {
71
90
                        /* no-op */
72
 
                } else if (strcmp(name, "UPDATE") == 0)
 
91
                } else if (strcmp(name, "UPDATE") == 0) {
 
92
                        if ((ctx->return_options & SEARCH_RETURN_UPDATE) != 0) {
 
93
                                client_send_command_error(cmd,
 
94
                                        "SEARCH return options have duplicate UPDATE.");
 
95
                                return FALSE;
 
96
                        }
73
97
                        ctx->return_options |= SEARCH_RETURN_UPDATE;
74
 
                else if (strcmp(name, "RELEVANCY") == 0)
 
98
                        if (imap_arg_get_list(args, &update_args)) {
 
99
                                if (!search_parse_fetch_att(ctx, update_args))
 
100
                                        return FALSE;
 
101
                                args++;
 
102
                        }
 
103
                } else if (strcmp(name, "RELEVANCY") == 0)
75
104
                        ctx->return_options |= SEARCH_RETURN_RELEVANCY;
76
105
                else if (strcmp(name, "PARTIAL") == 0) {
77
106
                        if (ctx->partial1 != 0) {
149
178
                /* too many updates */
150
179
                string_t *str = t_str_new(256);
151
180
                str_append(str, "* NO [NOUPDATE ");
152
 
                imap_quote_append_string(str, ctx->cmd->tag, FALSE);
 
181
                imap_append_quoted(str, ctx->cmd->tag);
153
182
                str_append_c(str, ']');
154
183
                client_send_line(client, str_c(str));
155
184
                ctx->return_options &= ~SEARCH_RETURN_UPDATE;
 
185
                imap_search_context_free(ctx);
156
186
                return;
157
187
        }
158
188
        result = mailbox_search_result_save(ctx->search_ctx,
163
193
        update->tag = i_strdup(ctx->cmd->tag);
164
194
        update->result = result;
165
195
        update->return_uids = ctx->cmd->uid;
 
196
        update->fetch_pool = ctx->fetch_pool;
 
197
        update->fetch_ctx = ctx->fetch_ctx;
 
198
        ctx->fetch_pool = NULL;
 
199
        ctx->fetch_ctx = NULL;
166
200
}
167
201
 
168
202
static void imap_search_send_result_standard(struct imap_search_context *ctx)
177
211
                for (seq = range->seq1; seq <= range->seq2; seq++)
178
212
                        str_printfa(str, " %u", seq);
179
213
                if (str_len(str) >= 1024-32) {
180
 
                        o_stream_send(ctx->cmd->client->output,
181
 
                                      str_data(str), str_len(str));
 
214
                        o_stream_nsend(ctx->cmd->client->output,
 
215
                                       str_data(str), str_len(str));
182
216
                        str_truncate(str, 0);
183
217
                }
184
218
        }
188
222
                            (unsigned long long)ctx->highest_seen_modseq);
189
223
        }
190
224
        str_append(str, "\r\n");
191
 
        o_stream_send(ctx->cmd->client->output,
192
 
                      str_data(str), str_len(str));
 
225
        o_stream_nsend(ctx->cmd->client->output, str_data(str), str_len(str));
193
226
}
194
227
 
195
228
static void
285
318
 
286
319
        str = str_new(default_pool, 1024);
287
320
        str_append(str, "* ESEARCH (TAG ");
288
 
        imap_quote_append_string(str, ctx->cmd->tag, FALSE);
 
321
        imap_append_string(str, ctx->cmd->tag);
289
322
        str_append_c(str, ')');
290
323
 
291
324
        if (ctx->cmd->uid)
318
351
                            (unsigned long long)ctx->highest_seen_modseq);
319
352
        }
320
353
        str_append(str, "\r\n");
321
 
        o_stream_send(client->output, str_data(str), str_len(str));
 
354
        o_stream_nsend(client->output, str_data(str), str_len(str));
322
355
        str_free(&str);
323
356
}
324
357
 
334
367
        }
335
368
        if ((ctx->return_options & SEARCH_RETURN_SAVE) != 0) {
336
369
                seq_range_array_add(&ctx->cmd->client->search_saved_uidset,
337
 
                                    0, mail->uid);
 
370
                                    mail->uid);
338
371
        }
339
372
        if ((ctx->return_options & SEARCH_RETURN_RELEVANCY) != 0) {
340
373
                const char *str;
491
524
                (void)client_handle_unfinished_cmd(cmd);
492
525
        else
493
526
                client_command_free(&cmd);
494
 
        (void)cmd_sync_delayed(client);
 
527
        cmd_sync_delayed(client);
495
528
 
496
529
        if (client->disconnected)
497
530
                client_destroy(client, NULL);
511
544
                return 1;
512
545
        }
513
546
 
514
 
        if (!search_parse_return_options(ctx, list_args))
 
547
        if (!search_parse_return_options(ctx, list_args)) {
 
548
                imap_search_context_free(ctx);
515
549
                return -1;
 
550
        }
516
551
 
517
552
        if ((ctx->return_options & SEARCH_RETURN_SAVE) != 0) {
518
553
                /* wait if there is another SEARCH SAVE command running. */
519
 
                cmd->search_save_result = TRUE;
520
 
                if (client_handle_search_save_ambiguity(cmd))
 
554
                if (client_handle_search_save_ambiguity(cmd)) {
 
555
                        imap_search_context_free(ctx);
521
556
                        return 0;
 
557
                }
522
558
 
523
559
                /* make sure the search result gets cleared if SEARCH fails */
524
560
                if (array_is_created(&cmd->client->search_saved_uidset))
525
561
                        array_clear(&cmd->client->search_saved_uidset);
526
562
                else
527
563
                        i_array_init(&cmd->client->search_saved_uidset, 128);
 
564
                cmd->search_save_result = TRUE;
528
565
        }
529
566
 
530
567
        *_args = args + 2;
554
591
        i_array_init(&ctx->result, 128);
555
592
        if ((ctx->return_options & SEARCH_RETURN_UPDATE) != 0)
556
593
                imap_search_result_save(ctx);
 
594
        else {
 
595
                i_assert(ctx->fetch_ctx == NULL);
 
596
        }
557
597
        if ((ctx->return_options & SEARCH_RETURN_RELEVANCY) != 0)
558
598
                i_array_init(&ctx->relevancy_scores, 128);
559
599
 
593
633
        array_free(&ctx->result);
594
634
        mail_search_args_deinit(ctx->sargs);
595
635
        mail_search_args_unref(&ctx->sargs);
 
636
        imap_search_context_free(ctx);
596
637
 
597
638
        ctx->cmd->context = NULL;
598
639
        return ret;
599
640
}
 
641
 
 
642
void imap_search_context_free(struct imap_search_context *ctx)
 
643
{
 
644
        if (ctx->fetch_ctx != NULL) {
 
645
                imap_fetch_free(&ctx->fetch_ctx);
 
646
                pool_unref(&ctx->fetch_pool);
 
647
        }
 
648
}
 
649
 
 
650
void imap_search_update_free(struct imap_search_update *update)
 
651
{
 
652
        if (update->fetch_ctx != NULL) {
 
653
                imap_fetch_free(&update->fetch_ctx);
 
654
                pool_unref(&update->fetch_pool);
 
655
        }
 
656
        mailbox_search_result_free(&update->result);
 
657
        i_free(update->tag);
 
658
}