imap-search.c revision 814bf67459ad405a157af0b8940602024d7fadfe
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "ostream.h"
#include "str.h"
#include "seq-range-array.h"
#include "time-util.h"
#include "imap-resp-code.h"
#include "imap-quote.h"
#include "imap-seqset.h"
#include "imap-util.h"
#include "mail-search-build.h"
#include "imap-fetch.h"
#include "imap-commands.h"
#include "imap-search-args.h"
#include "imap-search.h"
static int
{
return -1;
return -1;
}
return 0;
}
static bool
const struct imap_arg *update_args)
{
const char *error;
return FALSE;
}
return TRUE;
}
static bool
{
const struct imap_arg *update_args;
unsigned int idx;
while (!IMAP_ARG_IS_EOL(args)) {
"SEARCH return options contain non-atoms.");
return FALSE;
}
args++;
/* no-op */
"SEARCH return options have duplicate UPDATE.");
return FALSE;
}
return FALSE;
args++;
}
"PARTIAL can be used only once.");
return FALSE;
}
"PARTIAL range missing.");
return FALSE;
}
"PARTIAL range broken.");
return FALSE;
}
args++;
} else {
"Unknown SEARCH return option");
return FALSE;
}
}
return FALSE;
}
return FALSE;
}
if (ctx->return_options == 0)
return TRUE;
}
const struct mail_search_arg *sargs)
{
case SEARCH_SEQSET:
break;
case SEARCH_MODSEQ:
break;
case SEARCH_OR:
case SEARCH_SUB:
break;
default:
break;
}
}
}
{
struct mail_search_result *result;
struct imap_search_update *update;
/* too many updates */
return;
}
}
{
str_truncate(str, 0);
}
}
if (ctx->highest_seen_modseq != 0) {
(unsigned long long)ctx->highest_seen_modseq);
}
}
static void
{
unsigned int i, count, delete_count;
/* we need to be able to handle non-sorted seq ranges (for SORT
replies), so do this ourself instead of using seq_range_array_*()
functions. */
/* delete everything up to partial1 */
delete_count = 0;
for (i = n = 0; i < count; i++) {
delete_count = i;
break;
}
n += diff + 1;
}
if (i == count) {
/* partial1 points past the result */
} else {
/* delete everything after partial2 */
break;
}
n += diff + 1;
}
}
/* no results (in range) */
} else {
}
}
static void
{
const float *scores;
unsigned int i, count;
float diff, imap_score;
if (count == 0)
return;
/* we'll need to convert float scores to numbers 1..100
FIXME: would be a good idea to try to detect non-linear score
mappings and convert them better.. */
if (diff == 0)
diff = 1.0;
for (i = 0; i < count; i++) {
if (i > 0)
if (imap_score < 1)
else
}
}
{
unsigned int count;
return;
}
if (ctx->return_options ==
/* we only wanted to save the result, don't return
ESEARCH result. */
return;
}
if (count > 0) {
}
}
}
if (ctx->highest_seen_modseq != 0) {
(unsigned long long)ctx->highest_seen_modseq);
}
}
static void
{
}
}
const char *str;
float score;
score = 0;
else
}
}
{
unsigned int count;
/* only append the data. this is especially important when we're
returning a sort result. */
} else {
}
}
{
enum mailbox_sync_flags sync_flags;
unsigned int count;
const char *ok_reply;
(void)imap_search_deinit(ctx);
return TRUE;
}
if (count == 0) {
id_min = 0;
id_max = 0;
} else {
}
(opts & ~(SEARCH_RETURN_NORESULTS |
SEARCH_RETURN_MIN | SEARCH_RETURN_MAX)) == 0;
ctx->result_count++;
if (minmax) {
if ((opts & SEARCH_RETURN_MAX) != 0)
/* return option updates are delayed until
}
continue;
}
if ((opts & ~(SEARCH_RETURN_NORESULTS |
SEARCH_RETURN_COUNT)) == 0) {
/* we only want to count (and get modseqs) */
continue;
}
}
if (tryagain)
return FALSE;
if ((opts & SEARCH_RETURN_MIN) != 0) {
i_unreached();
} else {
}
}
if ((opts & SEARCH_RETURN_MAX) != 0) {
i_unreached();
} else {
}
}
}
if (imap_search_deinit(ctx) < 0) {
return TRUE;
}
}
{
bool finished;
if (!finished)
(void)client_handle_unfinished_cmd(cmd);
else
if (client->disconnected)
else
}
{
return 1;
}
return -1;
}
/* wait if there is another SEARCH SAVE command running. */
return 0;
}
/* make sure the search result gets cleared if SEARCH fails */
else
}
return 1;
}
struct mail_search_args *sargs,
const enum mail_sort_type *sort_program)
{
if (ctx->have_modseqs) {
}
ctx->search_ctx =
else {
}
if (cmd_search_more(cmd))
return TRUE;
/* we may have moved onto syncing by now */
return FALSE;
}
{
int ret = 0;
ret = -1;
else {
/* search failed */
}
return ret;
}
{
}
}
{
}
}