mail-search.h revision 1cc4d4d1a2ca48a82434da470872392c1bdcb651
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch#ifndef MAIL_SEARCH_H
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#define MAIL_SEARCH_H
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#include "seq-range-array.h"
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#include "mail-types.h"
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#include "mail-thread.h"
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenenum mail_search_arg_type {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_OR,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_SUB,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
551fef69c0633ae3c7738038e047a7c0762d9599Timo Sirainen /* sequence sets */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_ALL,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_SEQSET,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_UIDSET,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* flags */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_FLAGS,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_KEYWORDS,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* dates (date_type required) */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_BEFORE,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_ON, /* time must point to beginning of the day */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_SINCE,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* sizes */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_SMALLER,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_LARGER,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* headers */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_HEADER,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_HEADER_ADDRESS,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_HEADER_COMPRESS_LWSP,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* body */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_BODY,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_TEXT,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* extensions */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_MODSEQ,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_INTHREAD,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_GUID,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_MAILBOX,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_MAILBOX_GUID,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_MAILBOX_GLOB,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen SEARCH_REAL_UID
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenenum mail_search_date_type {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_DATE_TYPE_SENT = 1,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_DATE_TYPE_RECEIVED,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_DATE_TYPE_SAVED
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenenum mail_search_arg_flag {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* For BEFORE/SINCE/ON searches: Don't drop timezone from
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen comparisons */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_ARG_FLAG_USE_TZ = 0x01,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenenum mail_search_modseq_type {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_MODSEQ_TYPE_ANY = 0,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_MODSEQ_TYPE_PRIVATE,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen MAIL_SEARCH_MODSEQ_TYPE_SHARED
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstruct mail_search_modseq {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen uint64_t modseq;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_search_modseq_type type;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstruct mail_search_arg {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_arg *next;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_search_arg_type type;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_arg *subargs;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen ARRAY_TYPE(seq_range) seqset;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const char *str;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen time_t time;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen uoff_t size;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_flags flags;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_search_arg_flag search_flags;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_search_date_type date_type;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen enum mail_thread_type thread_type;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_keywords *keywords;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_modseq *modseq;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_args *search_args;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_result *search_result;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct imap_match_glob *mailbox_glob;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen } value;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen void *context;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const char *hdr_field_name; /* for SEARCH_HEADER* */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int match_not:1; /* result = !result */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int match_always:1; /* result = 1 always */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int nonmatch_always:1; /* result = 0 always */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int fuzzy:1; /* use fuzzy matching for this arg */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen int result; /* -1 = unknown, 0 = unmatched, 1 = matched */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstruct mail_search_args {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen int refcount, init_refcount;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen pool_t pool;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mailbox *box;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_arg *args;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int simplified:1;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int have_inthreads:1;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* Stop mail_search_next() when finding a non-matching mail.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen (Could be useful when wanting to find only the oldest mails.) */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned int stop_on_nonmatch:1;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen};
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#define ARG_SET_RESULT(arg, res) \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen STMT_START { \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen (arg)->result = !(arg)->match_not ? (res) : \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen (res) == -1 ? -1 : !(res); \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen } STMT_END
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainentypedef void mail_search_foreach_callback_t(struct mail_search_arg *arg,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen void *context);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Allocate keywords for search arguments. If change_uidsets is TRUE,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen change uidsets to seqsets. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_init(struct mail_search_args *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mailbox *box, bool change_uidsets,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen ATTR_NULL(4);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Free keywords. The args can initialized afterwards again if needed.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen The args can be reused for other queries after calling this. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_deinit(struct mail_search_args *args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Convert sequence sets in args to UIDs. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_seq2uid(struct mail_search_args *args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Returns TRUE if the two search arguments are fully compatible.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen Always returns FALSE if there are seqsets, since they may point to different
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen messages depending on when the search is run. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenbool mail_search_args_equal(const struct mail_search_args *args1,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const struct mail_search_args *args2);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_ref(struct mail_search_args *args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_unref(struct mail_search_args **args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstruct mail_search_args *
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenmail_search_args_dup(const struct mail_search_args *args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstruct mail_search_arg *
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenmail_search_arg_dup(pool_t pool, const struct mail_search_arg *arg);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Reset the results in search arguments. match_always is reset only if
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen full_reset is TRUE. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_reset(struct mail_search_arg *args, bool full_reset);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* goes through arguments in list that don't have a result yet.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen Returns 1 = search matched, 0 = search unmatched, -1 = don't know yet */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenint mail_search_args_foreach(struct mail_search_arg *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen mail_search_foreach_callback_t *callback,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen void *context) ATTR_NULL(3);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#define mail_search_args_foreach(args, callback, context) \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen mail_search_args_foreach(args + \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen struct mail_search_arg *, typeof(context))), \
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen (mail_search_foreach_callback_t *)callback, context)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Fills have_headers and have_body based on if such search argument exists
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen that needs to be checked. Returns the headers that we're searching for, or
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen NULL if we're searching for TEXT. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenconst char *const *
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenmail_search_args_analyze(struct mail_search_arg *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen bool *have_headers, bool *have_body);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Returns FALSE if search query contains MAILBOX[_GLOB] args such that the
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen query can never match any messages in the given mailbox. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenbool mail_search_args_match_mailbox(struct mail_search_args *args,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi const char *vname, char sep);
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Simplify/optimize search arguments. Afterwards all OR/SUB args are
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen guaranteed to have match_not=FALSE. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_simplify(struct mail_search_args *args);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Append all args as IMAP SEARCH AND-query to the dest string and returns TRUE.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen If some search arg can't be written as IMAP SEARCH parameter, error_r is set
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen and FALSE is returned. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenbool mail_search_args_to_imap(string_t *dest, const struct mail_search_arg *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const char **error_r);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Like mail_search_args_to_imap(), but append only a single arg. */
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvibool mail_search_arg_to_imap(string_t *dest, const struct mail_search_arg *arg,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const char **error_r);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Serialization for search args' results. */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_result_serialize(const struct mail_search_args *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen buffer_t *dest);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid mail_search_args_result_deserialize(struct mail_search_args *args,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const unsigned char *data,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen size_t size);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen#endif
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen