return -1;
}
- if (mail_search_build_from_imap_args(args, charset,
+ if (mail_search_build_from_imap_args(mail_search_register_imap,
+ args, charset,
&sargs, &error) < 0) {
client_send_command_error(cmd, error);
return -1;
mail-search.c \
mail-search-build.c \
mail-search-register.c \
+ mail-search-register-human.c \
mail-search-register-imap.c \
mail-storage.c \
mail-storage-hooks.c \
#include <stdlib.h>
+int mail_search_build_next_astring(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ const char **value_r)
+{
+ if (IMAP_ARG_IS_EOL(*imap_args)) {
+ ctx->error = "Missing parameter for argument";
+ return -1;
+ }
+ if (!imap_arg_get_astring(*imap_args, value_r)) {
+ ctx->error = "Invalid parameter for argument";
+ return -1;
+ }
+
+ *imap_args += 1;
+ return 0;
+}
+
+struct mail_search_arg *
+mail_search_build_new(struct mail_search_build_context *ctx,
+ enum mail_search_arg_type type)
+{
+ struct mail_search_arg *arg;
+
+ arg = p_new(ctx->pool, struct mail_search_arg, 1);
+ arg->type = type;
+ return arg;
+}
+
+struct mail_search_arg *
+mail_search_build_str(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ enum mail_search_arg_type type)
+{
+ struct mail_search_arg *sarg;
+ const char *value;
+
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
+ return NULL;
+ sarg->value.str = p_strdup(ctx->pool, value);
+ return sarg;
+}
+
struct mail_search_arg *
mail_search_build_next(struct mail_search_build_context *ctx,
+ struct mail_search_arg *parent,
const struct imap_arg **imap_args)
{
- struct mail_search_arg **subargs, *sarg;
+ struct mail_search_arg *sarg;
+ struct mail_search_arg *old_parent = ctx->parent;
const struct imap_arg *listargs;
const char *key;
const struct mail_search_register_arg *reg_arg;
mail_search_register_fallback_t *fallback;
+ ctx->parent = parent;
+
if (IMAP_ARG_IS_EOL(*imap_args)) {
ctx->error = "Missing argument";
return NULL;
return NULL;
}
- sarg = p_new(ctx->pool, struct mail_search_arg, 1);
- sarg->type = SEARCH_SUB;
- subargs = &sarg->value.subargs;
- while (!IMAP_ARG_IS_EOL(listargs)) {
- *subargs = mail_search_build_next(ctx, &listargs);
- if (*subargs == NULL)
- return NULL;
- subargs = &(*subargs)->next;
- }
-
+ sarg = mail_search_build_list(ctx, listargs);
*imap_args += 1;
+ ctx->parent = old_parent;
return sarg;
}
ctx->error = p_strconcat(ctx->pool, "Unknown argument ",
key, NULL);
}
+
+ ctx->parent = old_parent;
+ return sarg;
+}
+
+struct mail_search_arg *
+mail_search_build_list(struct mail_search_build_context *ctx,
+ const struct imap_arg *imap_args)
+{
+ struct mail_search_arg *sarg, **subargs;
+ enum mail_search_arg_type cur_type = SEARCH_SUB;
+
+ sarg = p_new(ctx->pool, struct mail_search_arg, 1);
+ sarg->type = cur_type;
+
+ subargs = &sarg->value.subargs;
+ while (!IMAP_ARG_IS_EOL(imap_args)) {
+ sarg->type = SEARCH_SUB;
+ *subargs = mail_search_build_next(ctx, sarg, &imap_args);
+ if (*subargs == NULL)
+ return NULL;
+
+ if (cur_type == sarg->type) {
+ /* expected type */
+ } else if (cur_type == SEARCH_SUB) {
+ /* type changed. everything in this list must now
+ belong to this type. */
+ cur_type = sarg->type;
+ } else {
+ ctx->error = cur_type == SEARCH_OR ?
+ "Use parenthesis when using ORs" :
+ "Use parenthesis when mixing subtypes";
+ return NULL;
+ }
+ subargs = &(*subargs)->next;
+ }
return sarg;
}
-int mail_search_build_from_imap_args(const struct imap_arg *imap_args,
+int mail_search_build_from_imap_args(struct mail_search_register *reg,
+ const struct imap_arg *imap_args,
const char *charset,
struct mail_search_args **args_r,
const char **error_r)
{
struct mail_search_build_context ctx;
struct mail_search_args *args;
- struct mail_search_arg **sargs;
+ struct mail_search_arg *root;
*args_r = NULL;
*error_r = NULL;
memset(&ctx, 0, sizeof(ctx));
ctx.pool = args->pool;
- ctx.reg = mail_search_register_imap;
+ ctx.reg = reg;
- sargs = &args->args;
- while (!IMAP_ARG_IS_EOL(imap_args)) {
- *sargs = mail_search_build_next(&ctx, &imap_args);
- if (*sargs == NULL) {
- *error_r = t_strdup(ctx.error);
- pool_unref(&args->pool);
- return -1;
- }
- sargs = &(*sargs)->next;
+ root = mail_search_build_list(&ctx, imap_args);
+ if (root == NULL) {
+ *error_r = t_strdup(ctx.error);
+ pool_unref(&args->pool);
+ return -1;
+ }
+
+ if (root->type == SEARCH_SUB && !root->not) {
+ /* simple SUB root */
+ args->args = root->value.subargs;
+ } else {
+ args->args = root;
}
*args_r = args;
#define MAIL_SEARCH_BUILD_H
#include "mail-search.h"
+#include "mail-search-register.h"
struct imap_arg;
struct mailbox;
struct mail_search_build_context {
pool_t pool;
struct mail_search_register *reg;
+
+ struct mail_search_arg *parent;
const char *error;
};
struct mail_search_args *mail_search_build_init(void);
/* Convert IMAP SEARCH command compatible parameters to mail_search_args. */
-int mail_search_build_from_imap_args(const struct imap_arg *imap_args,
+int mail_search_build_from_imap_args(struct mail_search_register *reg,
+ const struct imap_arg *imap_args,
const char *charset,
struct mail_search_args **args_r,
const char **error_r);
void mail_search_build_add_seqset(struct mail_search_args *args,
uint32_t seq1, uint32_t seq2);
+int mail_search_build_next_astring(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ const char **value_r);
+
+struct mail_search_arg *
+mail_search_build_new(struct mail_search_build_context *ctx,
+ enum mail_search_arg_type type);
+struct mail_search_arg *
+mail_search_build_str(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ enum mail_search_arg_type type);
struct mail_search_arg *
mail_search_build_next(struct mail_search_build_context *ctx,
+ struct mail_search_arg *parent,
const struct imap_arg **imap_args);
+struct mail_search_arg *
+mail_search_build_list(struct mail_search_build_context *ctx,
+ const struct imap_arg *imap_args);
#endif
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "array.h"
+#include "settings-parser.h"
+#include "imap-date.h"
+#include "mail-search-register.h"
+#include "mail-search-build.h"
+
+#include <time.h>
+#include <ctype.h>
+
+struct mail_search_register *mail_search_register_human;
+
+static struct mail_search_arg *
+human_search_or(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args)
+{
+ /* this changes the parent arg to be an OR block instead of AND block */
+ ctx->parent->type = SEARCH_OR;
+ return mail_search_build_next(ctx, ctx->parent, imap_args);
+}
+
+static struct mail_search_arg *
+arg_new_human_date(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ enum mail_search_arg_type type,
+ enum mail_search_date_type date_type)
+{
+ struct mail_search_arg *sarg;
+ const char *value, *error;
+ struct tm tm;
+ unsigned int secs;
+ int tz;
+
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
+ return NULL;
+
+ /* a) yyyy-mm-dd
+ b) imap date-time
+ c) interval (e.g. n days) */
+ if (i_isdigit(value[0]) && i_isdigit(value[1]) &&
+ i_isdigit(value[2]) && i_isdigit(value[3]) && value[4] == '-' &&
+ i_isdigit(value[5]) && i_isdigit(value[6]) && value[7] == '-' &&
+ i_isdigit(value[8]) && i_isdigit(value[9]) && value[10] == '\0') {
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_year = (value[0]-'0') * 1000 + (value[1]-'0') * 100 +
+ (value[2]-'0') * 10 + (value[3]-'0');
+ tm.tm_mon = (value[5]-'0') * 10 + (value[6]-'0') - 1;
+ tm.tm_mday = (value[8]-'0') * 10 + (value[9]-'0');
+ sarg->value.time = mktime(&tm);
+ } else if (imap_parse_datetime(value, &sarg->value.time, &tz)) {
+ /* imap date */
+ } else if (settings_get_time(value, &secs, &error) == 0) {
+ sarg->value.time = ioloop_time - secs;
+ } else {
+ sarg->value.time = (time_t)-1;
+ }
+ sarg->value.search_flags = MAIL_SEARCH_ARG_FLAG_USE_TZ;
+
+ if (sarg->value.time == (time_t)-1) {
+ ctx->error = p_strconcat(ctx->pool,
+ "Invalid search date parameter: ", value, NULL);
+ return NULL;
+ }
+ sarg->value.date_type = date_type;
+ return sarg;
+}
+
+#define CALLBACK_DATE(_func, _type, _date_type) \
+static struct mail_search_arg *\
+human_search_##_func(struct mail_search_build_context *ctx, \
+ const struct imap_arg **imap_args) \
+{ \
+ return arg_new_human_date(ctx, imap_args, _type, _date_type); \
+}
+CALLBACK_DATE(before, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_RECEIVED);
+CALLBACK_DATE(on, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_RECEIVED);
+CALLBACK_DATE(since, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_RECEIVED);
+
+CALLBACK_DATE(sentbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SENT);
+CALLBACK_DATE(senton, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SENT);
+CALLBACK_DATE(sentsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SENT);
+
+CALLBACK_DATE(savedbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SAVED);
+CALLBACK_DATE(savedon, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SAVED);
+CALLBACK_DATE(savedsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SAVED);
+
+static struct mail_search_arg *
+arg_new_human_size(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args,
+ enum mail_search_arg_type type)
+{
+ struct mail_search_arg *sarg;
+ const char *value, *error;
+
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
+ return NULL;
+
+ if (settings_get_size(value, &sarg->value.size, &error) < 0) {
+ ctx->error = p_strdup(ctx->pool, error);
+ return NULL;
+ }
+ return sarg;
+}
+
+static struct mail_search_arg *
+human_search_larger(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args)
+{
+ return arg_new_human_size(ctx, imap_args, SEARCH_LARGER);
+}
+
+static struct mail_search_arg *
+human_search_smaller(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args)
+{
+ return arg_new_human_size(ctx, imap_args, SEARCH_SMALLER);
+}
+
+static struct mail_search_arg *
+human_search_guid(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args)
+{
+ return mail_search_build_str(ctx, imap_args, SEARCH_GUID);
+}
+
+static struct mail_search_arg *
+human_search_mailbox(struct mail_search_build_context *ctx,
+ const struct imap_arg **imap_args)
+{
+ return mail_search_build_str(ctx, imap_args, SEARCH_MAILBOX);
+}
+
+static const struct mail_search_register_arg human_register_args[] = {
+ { "OR", human_search_or },
+
+ /* dates */
+ { "BEFORE", human_search_before },
+ { "ON", human_search_on },
+ { "SINCE", human_search_since },
+ { "SENTBEFORE", human_search_sentbefore },
+ { "SENTON", human_search_senton },
+ { "SENTSINCE", human_search_sentsince },
+ { "SAVEDBEFORE", human_search_savedbefore },
+ { "SAVEDON", human_search_savedon },
+ { "SAVEDSINCE", human_search_savedsince },
+ { "X-SAVEDBEFORE", human_search_savedbefore },
+ { "X-SAVEDON", human_search_savedon },
+ { "X-SAVEDSINCE", human_search_savedsince },
+
+ /* sizes */
+ { "LARGER", human_search_larger },
+ { "SMALLER", human_search_smaller },
+
+ /* Other Dovecot extensions: */
+ { "GUID", human_search_guid },
+ { "MAILBOX", human_search_mailbox }
+};
+
+struct mail_search_register *
+mail_search_register_init_human(struct mail_search_register *imap_register)
+{
+ struct mail_search_register *reg;
+ mail_search_register_fallback_t *fallback;
+ ARRAY_DEFINE(copy_args, const struct mail_search_register_arg);
+ const struct mail_search_register_arg *human_args, *imap_args;
+ unsigned int i, j, human_count, imap_count;
+ int ret;
+
+ reg = mail_search_register_init();
+ mail_search_register_add(reg, human_register_args,
+ N_ELEMENTS(human_register_args));
+
+ /* find and register args in imap that don't exist in human */
+ imap_args = mail_search_register_get(imap_register, &imap_count);
+ human_args = mail_search_register_get(reg, &human_count);
+ t_array_init(©_args, imap_count);
+ for (i = j = 0; i < imap_count && j < human_count; ) {
+ ret = strcmp(imap_args[i].key, human_args[j].key);
+ if (ret < 0) {
+ array_append(©_args, &imap_args[i], 1);
+ i++;
+ } else if (ret > 0) {
+ j++;
+ } else {
+ i++; j++;
+ }
+ }
+ for (; i < imap_count; i++)
+ array_append(©_args, &imap_args[i], 1);
+
+ imap_args = array_get(©_args, &imap_count);
+ mail_search_register_add(reg, imap_args, imap_count);
+
+ if (mail_search_register_get_fallback(imap_register, &fallback))
+ mail_search_register_fallback(reg, fallback);
+ return reg;
+}
#include <stdlib.h>
-static struct mail_search_arg *
-search_arg_new(pool_t pool, enum mail_search_arg_type type)
-{
- struct mail_search_arg *arg;
-
- arg = p_new(pool, struct mail_search_arg, 1);
- arg->type = type;
- return arg;
-}
-
-static int
-arg_get_next(struct mail_search_build_context *ctx,
- const struct imap_arg **imap_args, const char **value_r)
-{
- if (IMAP_ARG_IS_EOL(*imap_args)) {
- ctx->error = "Missing parameter for argument";
- return -1;
- }
- if (!imap_arg_get_astring(*imap_args, value_r)) {
- ctx->error = "Invalid parameter for argument";
- return -1;
- }
-
- *imap_args += 1;
- return 0;
-}
+struct mail_search_register *mail_search_register_imap;
static struct mail_search_arg *
imap_search_fallback(struct mail_search_build_context *ctx,
if (*key == '*' || (*key >= '0' && *key <= '9')) {
/* <message-set> */
- sarg = search_arg_new(ctx->pool, SEARCH_SEQSET);
+ sarg = mail_search_build_new(ctx, SEARCH_SEQSET);
p_array_init(&sarg->value.seqset, ctx->pool, 16);
if (imap_seq_set_parse(key, &sarg->value.seqset) < 0) {
ctx->error = "Invalid messageset";
{
struct mail_search_arg *sarg;
- sarg = mail_search_build_next(ctx, imap_args);
+ sarg = mail_search_build_next(ctx, ctx->parent, imap_args);
if (sarg != NULL)
sarg->not = !sarg->not;
return sarg;
struct mail_search_arg *sarg, **subargs;
/* <search-key1> <search-key2> */
- sarg = search_arg_new(ctx->pool, SEARCH_OR);
+ sarg = mail_search_build_new(ctx, SEARCH_OR);
subargs = &sarg->value.subargs;
for (;;) {
- *subargs = mail_search_build_next(ctx, imap_args);
+ *subargs = mail_search_build_next(ctx, sarg, imap_args);
if (*subargs == NULL)
return NULL;
subargs = &(*subargs)->next;
*imap_args += 1;
}
- *subargs = mail_search_build_next(ctx, imap_args);
+ *subargs = mail_search_build_next(ctx, sarg, imap_args);
if (*subargs == NULL)
return NULL;
return sarg;
}
-static struct mail_search_arg *
-arg_new_str(struct mail_search_build_context *ctx,
- const struct imap_arg **imap_args,
- enum mail_search_arg_type type)
-{
- struct mail_search_arg *sarg;
- const char *value;
-
- sarg = search_arg_new(ctx->pool, type);
- if (arg_get_next(ctx, imap_args, &value) < 0)
- return NULL;
- sarg->value.str = p_strdup(ctx->pool, value);
- return sarg;
-}
-
#define CALLBACK_STR(_func, _type) \
static struct mail_search_arg *\
imap_search_##_func(struct mail_search_build_context *ctx, \
const struct imap_arg **imap_args) \
{ \
- return arg_new_str(ctx, imap_args, _type); \
+ return mail_search_build_str(ctx, imap_args, _type); \
}
static struct mail_search_arg *
imap_search_all(struct mail_search_build_context *ctx,
const struct imap_arg **imap_args ATTR_UNUSED)
{
- return search_arg_new(ctx->pool, SEARCH_ALL);
+ return mail_search_build_new(ctx, SEARCH_ALL);
}
static struct mail_search_arg *
struct mail_search_arg *sarg;
/* <message set> */
- if ((sarg = arg_new_str(ctx, imap_args, SEARCH_UIDSET)) == NULL)
+ sarg = mail_search_build_str(ctx, imap_args, SEARCH_UIDSET);
+ if (sarg == NULL)
return NULL;
p_array_init(&sarg->value.seqset, ctx->pool, 16);
const struct imap_arg **imap_args ATTR_UNUSED) \
{ \
struct mail_search_arg *sarg; \
- sarg = search_arg_new(ctx->pool, SEARCH_FLAGS); \
+ sarg = mail_search_build_new(ctx, SEARCH_FLAGS); \
sarg->value.flags = _flag; \
sarg->not = _not; \
return sarg; \
struct mail_search_arg *sarg;
/* NEW == (RECENT UNSEEN) */
- sarg = search_arg_new(ctx->pool, SEARCH_SUB);
+ sarg = mail_search_build_new(ctx, SEARCH_SUB);
sarg->value.subargs = imap_search_recent(ctx, NULL);
sarg->value.subargs->next = imap_search_unseen(ctx, NULL);
return sarg;
struct mail_search_arg *sarg;
const char *value;
- sarg = search_arg_new(ctx->pool, type);
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
if (!imap_parse_date(value, &sarg->value.time)) {
ctx->error = "Invalid search date parameter";
struct mail_search_arg *sarg;
const char *value;
- sarg = search_arg_new(ctx->pool, type);
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
if (str_to_uoff(value, &sarg->value.size) < 0) {
struct mail_search_arg *sarg;
const char *value;
- sarg = search_arg_new(ctx->pool, type);
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
sarg->hdr_field_name = p_strdup(ctx->pool, hdr_name);
if (imap_arg_get_astring(*imap_args, &value) && *value == '\0') { \
/* optimization: BODY "" matches everything */ \
*imap_args += 1; \
- return search_arg_new(ctx->pool, SEARCH_ALL); \
+ return mail_search_build_new(ctx, SEARCH_ALL); \
} \
- return arg_new_str(ctx, imap_args, _type); \
+ return mail_search_build_str(ctx, imap_args, _type); \
}
CALLBACK_BODY(body, SEARCH_BODY);
CALLBACK_BODY(text, SEARCH_TEXT);
const char *value;
uint32_t interval;
- sarg = search_arg_new(ctx->pool, type);
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ sarg = mail_search_build_new(ctx, type);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
if (str_to_uint32(value, &interval) < 0 || interval == 0) {
const char *value;
/* [<name> <type>] <modseq> */
- sarg = search_arg_new(ctx->pool, SEARCH_MODSEQ);
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ sarg = mail_search_build_new(ctx, SEARCH_MODSEQ);
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
sarg->value.modseq = p_new(ctx->pool, struct mail_search_modseq, 1);
if (arg_modseq_set_name(ctx, sarg, value) < 0)
return NULL;
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
if (arg_modseq_set_type(ctx, sarg->value.modseq, value) < 0)
return NULL;
- if (arg_get_next(ctx, imap_args, &value) < 0)
+ if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
return NULL;
}
if (str_to_uint64(value, &sarg->value.modseq->modseq) < 0) {
struct mail_search_arg *sarg;
/* SEARCHRES: delay initialization */
- sarg = search_arg_new(ctx->pool, SEARCH_UIDSET);
+ sarg = mail_search_build_new(ctx, SEARCH_UIDSET);
sarg->value.str = "$";
p_array_init(&sarg->value.seqset, ctx->pool, 16);
return sarg;
}
*imap_args += 1;
- sarg = search_arg_new(ctx->pool, SEARCH_INTHREAD);
+ sarg = mail_search_build_new(ctx, SEARCH_INTHREAD);
sarg->value.thread_type = thread_type;
- sarg->value.subargs = mail_search_build_next(ctx, imap_args);
+ sarg->value.subargs = mail_search_build_next(ctx, sarg, imap_args);
if (sarg->value.subargs == NULL)
return NULL;
return sarg;
CALLBACK_STR(x_guid, SEARCH_GUID);
CALLBACK_STR(x_mailbox, SEARCH_MAILBOX);
-const struct mail_search_register_arg mail_search_register_imap[] = {
+const struct mail_search_register_arg imap_register_args[] = {
/* argument set operations */
{ "NOT", imap_search_not },
{ "OR", imap_search_or },
struct mail_search_register *reg;
reg = mail_search_register_init();
- mail_search_register_add(reg, mail_search_register_imap,
- N_ELEMENTS(mail_search_register_imap));
+ mail_search_register_add(reg, imap_register_args,
+ N_ELEMENTS(imap_register_args));
mail_search_register_fallback(reg, imap_search_fallback);
return reg;
}
i_free(reg);
}
-static int
-mail_search_register_arg_cmp(const struct mail_search_register_arg *arg1,
- const struct mail_search_register_arg *arg2)
-{
- return strcmp(arg1->key, arg2->key);
-}
-
void mail_search_register_add(struct mail_search_register *reg,
const struct mail_search_register_arg *arg,
unsigned int count)
reg->fallback = fallback;
}
+static int
+mail_search_register_arg_cmp(const struct mail_search_register_arg *arg1,
+ const struct mail_search_register_arg *arg2)
+{
+ return strcmp(arg1->key, arg2->key);
+}
+
+const struct mail_search_register_arg *
+mail_search_register_get(struct mail_search_register *reg,
+ unsigned int *count_r)
+{
+ if (!reg->args_sorted) {
+ array_sort(®->args, mail_search_register_arg_cmp);
+ reg->args_sorted = TRUE;
+ }
+
+ return array_get(®->args, count_r);
+}
+
const struct mail_search_register_arg *
mail_search_register_find(struct mail_search_register *reg, const char *key)
{
const struct imap_arg **imap_args);
};
+extern struct mail_search_register *mail_search_register_imap;
+extern struct mail_search_register *mail_search_register_human;
+
typedef struct mail_search_arg *
mail_search_register_fallback_t(struct mail_search_build_context *ctx,
const char *key,
void mail_search_register_fallback(struct mail_search_register *reg,
mail_search_register_fallback_t *fallback);
+/* Return all registered args sorted. */
+const struct mail_search_register_arg *
+mail_search_register_get(struct mail_search_register *reg,
+ unsigned int *count_r);
+
/* Find key's registered arg, or NULL if not found. */
const struct mail_search_register_arg *
mail_search_register_find(struct mail_search_register *reg, const char *key);
mail_search_register_fallback_t **fallback_r);
struct mail_search_register *mail_search_register_init_imap(void);
+struct mail_search_register *
+mail_search_register_init_human(struct mail_search_register *imap_register);
#endif
/* Storage's module_id for mail_index. */
extern struct mail_module_register mail_module_register;
-extern struct mail_search_register *mail_search_register_imap;
-
#define MAIL_STORAGE_CONTEXT(obj) \
MODULE_CONTEXT(obj, mail_storage_mail_index_module)
extern MODULE_CONTEXT_DEFINE(mail_storage_mail_index_module,
struct mail_storage_module_register mail_storage_module_register = { 0 };
struct mail_module_register mail_module_register = { 0 };
-struct mail_search_register *mail_search_register_imap;
struct mail_storage_mail_index_module mail_storage_mail_index_module =
MODULE_CONTEXT_INIT(&mail_index_module_register);
mail_storage_hooks_init();
i_array_init(&mail_storage_classes, 8);
mail_search_register_imap = mail_search_register_init_imap();
+ mail_search_register_human =
+ mail_search_register_init_human(mail_search_register_imap);
}
void mail_storage_deinit(void)
{
+ mail_search_register_deinit(&mail_search_register_human);
mail_search_register_deinit(&mail_search_register_imap);
if (array_is_created(&mail_storage_classes))
array_free(&mail_storage_classes);
if (ret < 0) {
sargs = NULL;
*error_r = t_strdup(imap_parser_get_error(parser, &fatal));
- } else if (mail_search_build_from_imap_args(args, "UTF-8", &sargs,
+ } else if (mail_search_build_from_imap_args(mail_search_register_imap,
+ args, "UTF-8", &sargs,
error_r) < 0)
sargs = NULL;