/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "str.h"
#include "ostream.h"
#include "imap-quote.h"
#include "mailbox-list-iter.h"
#include "mailbox-list-notify.h"
#include "mail-search.h"
#include "mail-search-build.h"
#include "imap-commands.h"
#include "imap-fetch.h"
#include "imap-list.h"
#include "imap-status.h"
#include "imap-notify.h"
const struct mailbox_list_notify_rec *rec,
enum mailbox_info_flags flags)
{
if (ns_sep == '\\')
}
}
const struct mailbox_list_notify_rec *rec)
{
}
MAILBOX_LIST_NOTIFY_EXPUNGES)) != 0)
/* if HIGHESTMODSEQ isn't being sent, don't send anything */
}
/* don't send anything */
/* hide permission errors from client. we don't want to leak
information about existence of mailboxes where user doesn't
have access to */
if (error != MAIL_ERROR_PERM)
ret = -1;
} else {
}
mailbox_free(&box);
return ret;
}
static int
const struct mailbox_list_notify_rec *rec)
{
int ret;
&mailbox_flags) < 0)
mailbox_flags = 0;
return ret;
}
return ret;
}
&mailbox_flags) < 0)
mailbox_flags = 0;
return ret;
}
&mailbox_flags) < 0)
mailbox_flags = 0;
mailbox_flags | MAILBOX_SUBSCRIBED)) < 0)
return ret;
}
&mailbox_flags) < 0)
mailbox_flags = 0;
return ret;
}
MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES)) != 0) {
return ret;
}
return 1;
}
static bool
const struct imap_notify_mailboxes *notify_boxes,
const struct mailbox_list_notify_rec *rec)
{
/* check for mailbox list events first */
if ((wanted_events & IMAP_NOTIFY_EVENT_MAILBOX_NAME) != 0) {
MAILBOX_LIST_NOTIFY_RENAME)) != 0)
return TRUE;
}
if ((wanted_events & IMAP_NOTIFY_EVENT_SUBSCRIPTION_CHANGE) != 0) {
MAILBOX_LIST_NOTIFY_UNSUBSCRIBE)) != 0)
return TRUE;
}
/* if this is an event for the selected mailbox, ignore it */
return FALSE;
if ((wanted_events & (IMAP_NOTIFY_EVENT_MESSAGE_NEW |
IMAP_NOTIFY_EVENT_FLAG_CHANGE)) != 0) {
return TRUE;
}
if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_NEW) != 0) {
return TRUE;
}
if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) != 0) {
return TRUE;
}
if ((wanted_events & IMAP_NOTIFY_EVENT_FLAG_CHANGE) != 0) {
return TRUE;
}
return FALSE;
}
const struct imap_notify_mailboxes *notify_boxes,
const char *vname)
{
const char *const *namep;
char ns_sep;
bool ret;
switch (notify_boxes->type) {
mailbox_free(&box);
return ret;
case IMAP_NOTIFY_TYPE_SUBTREE:
if (name_len == 0) {
/* everything under root. NOTIFY spec itself
doesn't define this, but we use it for
implementing "personal" */
return TRUE;
}
return TRUE;
}
break;
case IMAP_NOTIFY_TYPE_MAILBOX:
return TRUE;
}
break;
}
return FALSE;
}
static bool
const struct mailbox_list_notify_rec *rec)
{
return TRUE;
}
return FALSE;
}
{
return 0; /* notifications not supported in this namespace */
} T_END;
if (ret2 <= 0)
break;
}
if (ret < 0) {
/* failed to get some notifications */
return -1;
}
return ret2;
}
static int
{
int ret;
return 1;
return ret;
/* finished the FETCH */
if (imap_fetch_end(fetch_ctx) < 0)
return -1;
return 1;
}
{
/* send notifications for selected mailbox first. note that it may
leave the client's output stream in the middle of a FETCH reply. */
ret = -1;
}
}
/* send notifications for non-selected mailboxes */
if (ret == 0)
break;
if (imap_client_notify_ns(notify_ns) < 0)
ret = -1;
}
if (ret < 0) {
"* NO NOTIFY error, some events may have got lost");
}
return ret;
}
{
/* FETCH notifications not enabled in this session */
return 1;
}
return imap_client_notify_more(client);
return imap_client_notify_more(client);
}
{
}
{
}
static enum mailbox_list_notify_event
{
if ((events & IMAP_NOTIFY_EVENT_MESSAGE_NEW) != 0) {
}
if ((events & IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) != 0) {
}
if ((events & IMAP_NOTIFY_EVENT_FLAG_CHANGE) != 0) {
}
if ((events & IMAP_NOTIFY_EVENT_MAILBOX_NAME) != 0) {
}
if ((events & IMAP_NOTIFY_EVENT_SUBSCRIPTION_CHANGE) != 0) {
}
return ret;
}
{
/* create a fake command to handle this */
i_unreached();
(void)cmd_sync_delayed(client);
}
{
/* mailbox not selected */
return;
}
/* client doesn't want selected mailbox notifications */
return;
}
}
{
}
{
return;
if (client->command_queue_size > 0) {
/* don't add it until all commands are finished */
return;
}
/* add mailbox watch back after a small delay. if another command
is started this timeout is aborted. */
}
{
return;
/* remove mailbox watcher before starting any commands */
if (ctx->watching_mailbox) {
}
}
{
notify_events = 0;
}
/* notifications not supported */
} else {
ret = 0;
}
}
/* enable NOTIFY as long as even one namespace supports it,
ignore the rest */
return ret;
}
{
}
}
{
}
}