imap-fetch.c revision 83bb013a99f0936995f9c7a1077822662d8fefdb
/* Copyright (C) 2002-2004 Timo Sirainen */
#include "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 "commands.h"
#include "imap-fetch.h"
#include "imap-util.h"
#include <stdlib.h>
#define BODY_NIL_REPLY \
"\"text\" \"plain\" NIL NIL NIL \"7bit\" 0 0 NIL NIL NIL"
{
}
{
void *data;
if (fetch_handlers == NULL)
}
{
const struct imap_fetch_handler *h = handler_p;
int i;
for (i = 0; h->name[i] != '\0'; i++) {
return -1;
}
}
}
{
const struct imap_fetch_handler *handler;
sizeof(struct imap_fetch_handler),
sizeof(struct imap_fetch_handler),
return FALSE;
}
}
{
struct imap_fetch_context *ctx;
if (fetch_handlers == NULL) {
sizeof(default_handlers) /
sizeof(default_handlers[0]));
}
return ctx;
}
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);
}
}
struct mail_search_arg *search_arg)
{
const void *data;
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)
ctx->search_ctx =
}
{
const unsigned char *data;
/* 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++;
}
/* assume initially that we're locking it */
for (;;) {
if (ret <= 0) {
if (!ctx->line_partial) {
/* last line was fully sent */
}
return ret;
}
}
return 1;
break;
}
/* first non-buffered handler.
flush the buffer. */
if (imap_fetch_flush_buffer(ctx) < 0)
return -1;
}
t_push();
t_pop();
if (ret == 0) {
if (!ctx->line_partial) {
/* last line was fully sent */
}
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;
}
{
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
{
"(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)",
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-01-1970 00:00:00 +0000\"",
return TRUE;
}
void *context __attr_unused__)
{
return 1;
}
static bool
{
return TRUE;
}
{ "BODY", fetch_body_init },
{ "BODYSTRUCTURE", fetch_bodystructure_init },
{ "ENVELOPE", fetch_envelope_init },
{ "FLAGS", fetch_flags_init },
{ "INTERNALDATE", fetch_internaldate_init },
{ "RFC822", fetch_rfc822_init },
{ "UID", fetch_uid_init }
};