cmd-search.c revision 4a6763472005adc13b1338ab7ca4d2cf4591fafb
/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "ostream.h"
#include "str.h"
#include "seq-range-array.h"
#include "commands.h"
#include "mail-search-build.h"
#include "imap-quote.h"
#include "imap-seqset.h"
#include "imap-util.h"
#include "imap-search.h"
enum search_return_options {
SEARCH_RETURN_ESEARCH = 0x0001,
SEARCH_RETURN_MIN = 0x0002,
SEARCH_RETURN_MAX = 0x0004,
SEARCH_RETURN_ALL = 0x0008,
SEARCH_RETURN_COUNT = 0x0010,
SEARCH_RETURN_MODSEQ = 0x0020,
SEARCH_RETURN_SAVE = 0x0040,
SEARCH_RETURN_UPDATE = 0x0080,
SEARCH_RETURN_PARTIAL = 0x0100
#define SEARCH_RETURN_NORESULTS \
};
struct imap_search_context {
struct client_command_context *cmd;
struct mailbox_transaction_context *trans;
struct mail_search_context *search_ctx;
struct mail_search_args *sargs;
unsigned int result_count;
struct timeval start_time;
};
static bool
{
unsigned int idx;
"SEARCH return options contain non-atoms.");
return FALSE;
}
args++;
"SEARCH PARTIAL range missing.");
return FALSE;
}
"SEARCH PARTIAL range broken.");
return FALSE;
}
args++;
} else {
"Unknown SEARCH return option");
return FALSE;
}
}
return FALSE;
}
"SEARCH PARTIAL conflicts with ALL");
return FALSE;
}
if (ctx->return_options == 0)
return TRUE;
}
{
case SEARCH_MODSEQ:
return TRUE;
case SEARCH_OR:
case SEARCH_SUB:
return TRUE;
break;
default:
break;
}
}
return FALSE;
}
{
struct mail_search_result *result;
struct imap_search_update *update;
/* too many updates */
return;
}
}
static void
struct mail_search_args *sargs)
{
}
}
{
unsigned int i, count;
for (i = 0; i < count; i++) {
str_truncate(str, 0);
}
}
if (ctx->highest_seen_modseq != 0) {
(unsigned long long)ctx->highest_seen_modseq);
}
}
static void
{
struct seq_range_iter iter;
/* no results (in range) */
return;
}
/* FIXME: we should save the search result for later use */
if (seq1 > 1)
}
}
{
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);
}
}
{
int ret = 0;
ret = -1;
else {
/* search failed */
}
return ret;
}
{
}
}
}
{
unsigned int count;
(void)imap_search_deinit(ctx);
return TRUE;
}
if (count == 0) {
id_max = 0;
} else {
}
(opts & ~(SEARCH_RETURN_NORESULTS |
SEARCH_RETURN_MIN | SEARCH_RETURN_MAX)) == 0;
&tryagain) > 0) {
ctx->result_count++;
if (minmax) {
/* 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;
}
}
t_strdup_printf("OK Search completed (%d.%03d secs).",
}
{
bool finished;
if (!finished)
(void)client_handle_unfinished_cmd(cmd);
else
(void)cmd_sync_delayed(client);
}
{
struct imap_search_context *ctx;
struct mail_search_args *sargs;
int ret, args_count;
const char *charset;
if (args_count < 1) {
if (args_count == -2)
return FALSE;
"Missing SEARCH arguments.");
return TRUE;
}
if (!client_verify_open_mailbox(cmd))
return TRUE;
args++;
return TRUE;
args++;
/* wait if there is another SEARCH SAVE command
running. */
return FALSE;
}
} else {
}
/* make sure the search result gets cleared if SEARCH fails */
else
}
/* CHARSET specified */
args++;
"Invalid charset argument.");
return TRUE;
}
args++;
} else {
charset = "UTF-8";
}
if (ret <= 0)
return ret < 0;
if (cmd_search_more(cmd))
return TRUE;
/* we could have moved onto syncing by now */
return FALSE;
}