dnl ** capabilities
dnl **
-capability="IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS UIDPLUS LIST-EXTENDED I18NLEVEL=1 ENABLE CONDSTORE QRESYNC ESEARCH SEARCHRES"
+capability="IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS UIDPLUS LIST-EXTENDED I18NLEVEL=1 ENABLE CONDSTORE QRESYNC ESEARCH SEARCHRES WITHIN"
AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities)
CFLAGS="$CFLAGS $EXTRA_CFLAGS"
if (mail_get_received_date(ctx->mail, &date) < 0)
return -1;
- tm = localtime(&date);
- date += utc_offset(tm, date)*60;
+ if ((arg->value.search_flags &
+ MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) {
+ tm = localtime(&date);
+ date += utc_offset(tm, date)*60;
+ }
switch (arg->type) {
case SEARCH_BEFORE:
in searches. date is returned as UTC, so change it. */
if (mail_get_date(ctx->mail, &date, &timezone_offset) < 0)
return -1;
- date += timezone_offset * 60;
+ if ((arg->value.search_flags &
+ MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0)
+ date += timezone_offset * 60;
switch (arg->type) {
case SEARCH_SENTBEFORE:
/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "ioloop.h"
#include "imap-date.h"
#include "imap-parser.h"
#include "imap-messageset.h"
return TRUE;
}
+#define ARG_NEW_INTERVAL(type) \
+ arg_new_interval(data, args, next_sarg, type)
+static bool
+arg_new_interval(struct search_build_data *data,
+ const struct imap_arg **args,
+ struct mail_search_arg **next_sarg,
+ enum mail_search_arg_type type)
+{
+ struct mail_search_arg *sarg;
+ const char *value;
+ unsigned long interval;
+ char *p;
+
+ *next_sarg = sarg = search_arg_new(data->pool, type);
+ if (!arg_get_next(data, args, &value))
+ return FALSE;
+
+ interval = strtoul(value, &p, 10);
+ if (interval == 0 || *p != '\0') {
+ data->error = "Invalid search interval parameter";
+ return FALSE;
+ }
+ sarg->value.search_flags = MAIL_SEARCH_ARG_FLAG_USE_TZ;
+ sarg->value.time = ioloop_time - interval;
+ return TRUE;
+}
+
#define ARG_NEW_HEADER(type, hdr_name) \
arg_new_header(data, args, next_sarg, type, hdr_name)
static bool
(*next_sarg)->not = TRUE;
return TRUE;
+ } if (strcmp(str, "OLDER") == 0) {
+ /* <interval> - WITHIN extension */
+ if (!ARG_NEW_INTERVAL(SEARCH_BEFORE))
+ return FALSE;
+
+ /* we need to match also equal, but standard BEFORE
+ compares with "<" */
+ (*next_sarg)->value.time++;
+ return TRUE;
}
break;
case 'R':
return TRUE;
}
break;
+ case 'Y':
+ if (strcmp(str, "YOUNGER") == 0) {
+ /* <interval> - WITHIN extension */
+ return ARG_NEW_INTERVAL(SEARCH_SINCE);
+ }
+ break;
case 'X':
if (strcmp(str, "X-BODY-FAST") == 0) {
/* <string> */
SEARCH_MODSEQ
};
+enum mail_search_arg_flag {
+ /* For (SENT)BEFORE/SINCE/ON searches: Don't drop timezone from
+ comparisons */
+ MAIL_SEARCH_ARG_FLAG_USE_TZ = 0x01,
+};
+
enum mail_search_modseq_type {
MAIL_SEARCH_MODSEQ_TYPE_ANY = 0,
MAIL_SEARCH_MODSEQ_TYPE_PRIVATE,
enum mail_flags flags;
struct mail_keywords *keywords;
struct mail_search_modseq *modseq;
+ enum mail_search_arg_flag search_flags;
} value;
void *context;