imap-fetch-body-section.c revision a77bddd704784189944b731f5ce774bfb4440e0b
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "buffer.h"
#include "istream.h"
#include "ostream.h"
#include "message-parser.h"
#include "message-send.h"
#include "mail-storage.h"
#include "imap-fetch.h"
#include <ctype.h>
#include <unistd.h>
/* For FETCH[HEADER.FIELDS*] we need to modify the header data before sending
it. We can either save it in memory and then send it, or we can parse it
twice, first calculating the size and then send it. This value specifies
the maximum amount of memory we allow to allocate before using
double-parsing. */
struct fetch_header_field_context {
struct imap_fetch_context *fetch_ctx;
const char *const *fields;
int (*match_func) (const char *const *, const char *, size_t);
unsigned int fix_nuls:1;
};
struct partial_cache {
unsigned int select_counter;
unsigned int uid;
int cr_skipped;
struct message_size pos;
};
static struct partial_cache partial = { 0, 0, 0, 0, { 0, 0, 0 } };
{
int cr_skipped;
/* we can use the cache */
} else {
}
return cr_skipped;
}
{
return 0;
}
/* fetch BODY[] or BODY[TEXT] */
const struct imap_fetch_body_data *body,
{
const char *str;
return FALSE;
if (fetch_header)
return FALSE;
!mail->has_no_nuls);
if (ret > 0) {
}
return ret >= 0;
}
static int header_match(const char *const *fields,
{
if (size == 0)
return FALSE;
name_start = name;
if (*field == '\0')
continue;
/* field has been uppercased long time ago while
parsing FETCH command */
break;
field++;
if (*field == '\0') {
return TRUE;
break;
}
}
}
return FALSE;
}
static int header_match_not(const char *const *fields,
{
}
{
return TRUE;
return TRUE;
return FALSE;
}
{
size_t i;
return TRUE;
}
}
}
for (i = 0; i < size; ) {
if (str[i] != 0) {
i++;
continue;
}
/* NUL found, change it to #128 */
} else {
return FALSE;
}
str += i+1;
size -= i+1;
i = 0;
}
}
return FALSE;
}
}
struct fetch_header_field_context *ctx)
{
struct message_header_parser_ctx *hdr_ctx;
struct message_header_line *hdr;
return FALSE;
}
/* Mime-Version + Content-* fields */
} else {
i_warning("BUG: Accepted invalid section from user: '%s'",
section);
return FALSE;
}
/* see if we want this field.
we always want the end-of-headers line */
continue;
break;
break;
}
break;
if (!hdr->no_newline) {
break;
}
}
return TRUE;
}
/* fetch wanted headers from given data */
const struct imap_fetch_body_data *body,
const char *header_section)
{
struct fetch_header_field_context hdr_ctx;
const char *str;
const void *data;
int failed;
/* HEADER, MIME, HEADER.FIELDS (list), HEADER.FIELDS.NOT (list) */
/* all headers */
return FALSE;
!mail->has_no_nuls) >= 0;
}
/* partial headers - copy the wanted fields into memory, inserting
missing CRs on the way. If the header is too large, calculate
the size first and then send the data directly to output stream. */
t_push();
/* first pass, we need at least the size */
!ctx->body_fetch_from_cache) {
} else {
(size_t)-1);
}
if (!failed) {
}
if (!failed) {
/* second pass, write the data to output stream */
if (!failed &&
&hdr_ctx))
} else {
}
}
t_pop();
return !failed;
}
const struct imap_fetch_body_data *body)
{
struct message_size hdr_size;
if (ctx->body_fetch_from_cache)
else {
return FALSE;
}
}
/* Find message_part for section (eg. 1.3.4) */
{
const struct message_part *part;
const char *path;
unsigned int num;
return FALSE;
/* get part number */
num = 0;
return FALSE;
path++;
}
if (*path == '.')
path++;
/* find the part */
} else {
/* only 1 allowed with non-multipart messages */
if (num != 1)
}
}
}
return TRUE;
}
/* fetch BODY[1.2] or BODY[1.2.TEXT] */
const struct imap_fetch_body_data *body,
{
const char *str;
return FALSE;
if (ret > 0) {
}
return ret >= 0;
}
const struct imap_fetch_body_data *body)
{
const struct message_part *part;
const char *section;
return FALSE;
/* part doesn't exist */
}
return FALSE;
}
i_warning("BUG: Accepted invalid section from user: '%s'",
return FALSE;
}
const struct imap_fetch_body_data *body,
{
}
i_warning("BUG: Accepted invalid section from user: '%s'",
return FALSE;
}