/* Copyright (c) 2002-2018 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
{
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;
}
}
}
{
/* too many updates */
return;
}
}
{
str_truncate(str, 0);
}
}
if (ctx->highest_seen_modseq != 0) {
}
}
static void
{
/* 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;
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) {
}
}
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 {
}
}
{
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;
/* Send the result also after failing. It might have something useful,
even though it didn't fully succeed. The client should be able to
realize that there was some failure because NO is returned. */
/* search failed */
}
return ret;
}
{
}
}
{
}
}