/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "str.h"
#include "mailbox-list-iter.h"
#include "imap-quote.h"
#include "imap-commands.h"
#include "imap-fetch.h"
#include "imap-list.h"
#include "imap-status.h"
#include "imap-notify.h"
static const char *imap_notify_event_names[] = {
"MessageNew", "MessageExpunge", "FlagChange", "AnnotationChange",
"MailboxName", "SubscriptionChange", "MailboxMetadataChange",
"ServerMetadataChange"
};
static int
enum imap_notify_event *event_r)
{
const char *str;
unsigned int i;
return -1;
for (i = 0; i < N_ELEMENTS(imap_notify_event_names); i++) {
return 0;
}
}
return -1;
}
static int
{
return -1; /* at least one attribute must be set */
}
static int
{
#define EV_NEW_OR_EXPUNGE \
const char *str;
/* no events for selected mailbox. this is also the default
when NOTIFY command doesn't specify it explicitly */
return -1; /* no extra parameters */
return 0;
}
return -1;
return -1; /* no extra parameters */
return -1; /* at least one event */
return -1;
if (event == IMAP_NOTIFY_EVENT_MESSAGE_NEW &&
/* MessageNew: list of fetch-att */
return -1;
list++;
}
}
/* if MessageNew or MessageExpunge is specified, both of them must */
return -1;
}
/* if FlagChange or AnnotationChange is specified,
MessageNew and MessageExpunge must also be specified */
if ((ctx->selected_events &
IMAP_NOTIFY_EVENT_ANNOTATION_CHANGE)) != 0 &&
return -1;
}
return 0;
}
static struct imap_notify_namespace *
struct mail_namespace *ns)
{
return notify_ns;
}
return notify_ns;
}
static struct imap_notify_mailboxes *
enum imap_notify_type type,
enum imap_notify_event events)
{
return notify_boxes;
}
return notify_boxes;
}
static void
enum imap_notify_type type,
enum imap_notify_event events)
{
const char *const *names;
unsigned int i, count;
/* we'll do only case-sensitive comparisons later,
so sanitize INBOX to be uppercase */
}
for (i = 0; i < count; ) {
/* exact duplicate, already added */
return;
}
if (type != IMAP_NOTIFY_TYPE_SUBTREE)
i++;
else {
/* see if one is a subtree of the other */
/* already matched in this subtree */
return;
}
/* we're adding a parent, remove the child */
} else {
i++;
}
}
}
}
enum imap_notify_event events)
{
}
}
}
static int
struct imap_notify_context *ctx)
{
if (!ctx->have_subscriptions)
return 0;
/* make sure subscriptions are refreshed at least once */
(void)mailbox_list_iter_next(iter);
if (mailbox_list_iter_deinit(&iter) < 0) {
return -1;
}
}
return 0;
}
enum imap_notify_event events)
{
}
}
static void
const char *name,
enum imap_notify_type type,
enum imap_notify_event events)
{
}
static int
enum imap_notify_type type,
enum imap_notify_event events)
{
const char *name;
return 0;
}
return -1;
return -1;
}
return 0;
}
static int
{
/* send STATUS replies for all matched mailboxes before
NOTIFY's OK reply */
args++;
}
return -1;
/* filter-mailboxes */
return -1;
event_group++;
/* setting events for selected mailbox.
handle specially. */
if (ctx->selected_set) {
return -1;
}
return -1;
continue;
}
return -1;
mailboxes = event_group++;
/* check that the mailboxes parameter is valid */
if (IMAP_ARG_IS_ASTRING(mailboxes))
;
return -1;
/* should have at least one mailbox */
return -1;
}
} else {
}
/* parse events */
/* NONE is the default, ignore this */
continue;
}
return -1;
event_mask = 0;
return -1;
event_mask |= event;
}
/* we can't currently know inboxes, so treat it the
same as personal */
event_mask) < 0)
return -1;
event_mask) < 0)
return -1;
} else {
return -1;
}
}
return 0;
}
static void
{
mailbox_flags = 0;
if (ns_sep == '\\')
}
static void
struct imap_notify_context *ctx,
const struct mailbox_info *info)
{
return;
/* don't send STATUS to selected mailbox */
return;
}
} else {
}
mailbox_free(&box);
}
{
if ((notify_boxes->events &
IMAP_NOTIFY_EVENT_FLAG_CHANGE)) != 0)
return TRUE;
}
return FALSE;
}
static void
struct imap_notify_context *ctx,
struct imap_notify_namespace *notify_ns)
{
return;
/* set _RETURN_SUBSCRIBED flag just in case IMAP_NOTIFY_TYPE_SUBSCRIBED
is used, which requires refreshing subscriptions */
break;
}
}
}
if (mailbox_list_iter_deinit(&iter) < 0) {
"* NO Mailbox listing failed");
}
}
struct imap_notify_context *ctx)
{
}
{
const char *str;
int ret = 0;
return FALSE;
ret = -1;
;
else
ret = -1;
if (ret < 0) {
"Invalid arguments.");
pool_unref(&pool);
return TRUE;
}
unsigned int i;
for (i = 0; i < N_ELEMENTS(imap_notify_event_names); i++) {
((1 << i) & UNSUPPORTED_EVENTS) != 0) {
}
}
pool_unref(&pool);
return TRUE;
}
/* selected mailbox only */
"NO [NOTIFICATIONOVERFLOW] Too many mailbox names");
pool_unref(&pool);
return TRUE;
/* tagline already sent */
pool_unref(&pool);
return TRUE;
} else if (imap_notify_begin(ctx) < 0) {
"NO [NOTIFICATIONOVERFLOW] NOTIFY not supported for these mailboxes.");
pool_unref(&pool);
return TRUE;
}
if (ctx->send_immediate_status)
}