imap-fetch.c revision de76b960297406115cf6bae473f004c08174b16a
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "array.h"
#include "buffer.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
#include "message-send.h"
#include "message-size.h"
#include "imap-date.h"
#include "mail-search-build.h"
#include "imap-commands.h"
#include "imap-quote.h"
#include "imap-fetch.h"
#include "imap-util.h"
#include <stdlib.h>
#include <ctype.h>
#define BODY_NIL_REPLY \
"\"text\" \"plain\" NIL NIL NIL \"7bit\" 0 0"
#define ENVELOPE_NIL_REPLY \
"(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)"
{
}
{
struct imap_fetch_handler *all_handlers;
unsigned int all_count;
}
{
const struct imap_fetch_handler *h = handler_p;
}
{
const char *lookup_name, *p;
unsigned int count;
sizeof(struct imap_fetch_handler),
return FALSE;
}
}
struct imap_fetch_context *
{
struct imap_fetch_context *ctx;
return ctx;
}
{
struct mail_search_arg *search_arg;
}
bool buffered, bool want_deinit,
{
/* partially because of broken clients, but also partially because
it potentially can make client implementations faster, we have a
buffered parameter which basically means that the handler promises
to write the output in ctx->cur_str. The cur_str is then sent to
client before calling any non-buffered handlers.
We try to keep the handler registration order the same as the
client requested them. This is especially useful to get UID
returned first, which some clients rely on..
*/
const struct imap_fetch_context_handler *handlers;
struct imap_fetch_context_handler h;
unsigned int i, size;
/* don't allow duplicate handlers */
for (i = 0; i < size; i++) {
return;
}
}
memset(&h, 0, sizeof(h));
h.want_deinit = want_deinit;
if (!buffered)
else {
&h, 1);
}
}
static void
{
unsigned int i, count;
/* FIXME: we could do removals from the middle as well */
for (i = 0; i < count; i++) {
break;
}
if (i > 0)
}
{
struct mailbox_transaction_context *trans;
struct mail_search_args *search_args;
struct mail_search_context *search_ctx;
struct mailbox_status status;
unsigned int i, count;
int ret = 0;
i = 0;
/* search UIDs in given range */
next_uid++;
else if (++i < count)
else
break;
} else {
/* next_uid .. mail->uid-1 are expunged */
i++;
}
}
else
}
}
if (i < count) {
i++;
}
for (; i < count; i++) {
}
if (mailbox_search_deinit(&search_ctx) < 0)
ret = -1;
(void)mailbox_transaction_commit(&trans);
return ret;
}
static int
{
int ret = 0;
/* return all expunged UIDs */
ret = -1;
}
}
if (array_count(&expunges) > 0) {
}
return ret;
}
{
const void *data;
if (ctx->send_vanished) {
if (imap_fetch_send_vanished(ctx) < 0) {
return -1;
}
}
if (ctx->flags_update_seen) {
else if (!ctx->flags_have_handler) {
}
}
MAIL_FETCH_STREAM_BODY)) == 0)) {
}
if ((ctx->fetch_data &
(MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0)
/* Delayed uidset -> seqset conversion. VANISHED needs the uidset. */
ctx->search_ctx =
return 0;
}
{
const unsigned char *data;
if (len == 0)
return 0;
/* there's an extra space at the end if we added any fetch items
to buffer */
len--;
}
return -1;
return 0;
}
{
const struct imap_fetch_context_handler *handler;
if (imap_fetch_flush_buffer(ctx) < 0)
return -1;
}
return 0;
}
{
const struct imap_fetch_context_handler *handlers;
unsigned int count;
int ret;
if (ret == 0)
return 0;
if (ret < 0) {
return -1;
/* not an error, just lost it. */
if (imap_fetch_send_nil_reply(ctx) < 0)
return -1;
} else {
return -1;
}
}
ctx->cur_offset = 0;
ctx->cur_handler++;
}
for (;;) {
if (ret <= 0)
return ret;
}
return 1;
break;
}
/* first non-buffered handler.
flush the buffer. */
if (imap_fetch_flush_buffer(ctx) < 0)
return -1;
}
T_BEGIN {
const struct imap_fetch_context_handler *h =
h->context);
} T_END;
if (ret == 0)
return 0;
if (ret < 0) {
/* not an error, just lost it. */
if (imap_fetch_send_nil_reply(ctx) < 0)
return -1;
} else {
return -1;
}
}
ctx->cur_offset = 0;
}
/* no non-buffered handlers */
if (imap_fetch_flush_buffer(ctx) < 0)
return -1;
}
return -1;
ctx->cur_handler = 0;
}
return 1;
}
{
int ret;
if (ret < 0)
if (ctx->line_partial) {
/* nothing can be sent until FETCH is finished */
}
return ret;
}
{
const struct imap_fetch_context_handler *handlers;
unsigned int i, count;
for (i = 0; i < count; i++) {
if (handlers[i].want_deinit)
}
if (!ctx->line_finished) {
if (imap_fetch_flush_buffer(ctx) < 0)
}
}
/* even if something failed, we want to commit changes to
cache, as well as possible \Seen flag changes for FETCH
replies we returned so far. */
}
}
void *context ATTR_UNUSED)
{
const char *body;
return -1;
else {
return -1;
}
return -1;
return 1;
}
{
return TRUE;
}
}
{
const char *bodystructure;
&bodystructure) < 0)
return -1;
else {
return -1;
}
return -1;
return 1;
}
static bool
{
return TRUE;
}
void *context ATTR_UNUSED)
{
const char *envelope;
return -1;
else {
return -1;
}
return -1;
return 1;
}
static bool
{
return TRUE;
}
void *context ATTR_UNUSED)
{
enum mail_flags flags;
const char *const *keywords;
/* Add \Seen flag */
} else if (ctx->flags_show_only_seen_changes) {
return 1;
}
return 1;
}
static bool
{
return TRUE;
}
void *context ATTR_UNUSED)
{
return -1;
return 1;
}
static bool
{
"\"01-Jan-1970 00:00:00 +0000\"",
return TRUE;
}
void *context ATTR_UNUSED)
{
(unsigned long long)modseq);
return 1;
}
static bool
{
fetch_modseq, NULL);
return TRUE;
}
void *context ATTR_UNUSED)
{
return 1;
}
static bool
{
return TRUE;
}
void *context ATTR_UNUSED)
{
const char *value;
return -1;
return 1;
}
static bool
{
return TRUE;
}
void *context ATTR_UNUSED)
{
const char *str;
i_panic("mailbox name not returned");
return 1;
}
static bool
const char *name,
{
return TRUE;
}
void *context ATTR_UNUSED)
{
return -1;
return 1;
}
static bool
{
"\"01-Jan-1970 00:00:00 +0000\"",
return TRUE;
}
static const struct imap_fetch_handler
{ "BODY", fetch_body_init },
{ "BODYSTRUCTURE", fetch_bodystructure_init },
{ "ENVELOPE", fetch_envelope_init },
{ "FLAGS", fetch_flags_init },
{ "INTERNALDATE", fetch_internaldate_init },
{ "MODSEQ", fetch_modseq_init },
{ "RFC822", fetch_rfc822_init },
{ "UID", fetch_uid_init },
{ "X-GUID", fetch_guid_init },
{ "X-MAILBOX", fetch_x_mailbox_init },
{ "X-SAVEDATE", fetch_x_savedate_init }
};
void imap_fetch_handlers_init(void)
{
}
void imap_fetch_handlers_deinit(void)
{
}