imap-fetch-body-section.c revision 3ed5b60132508928e82d685d901ad3e6f95b0df0
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "str.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 {
const char *const *fields;
int (*match_func) (const char *const *, const char *, size_t);
};
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;
}
/* fetch BODY[] or BODY[TEXT] */
const struct imap_fetch_body_data *body,
{
const char *str;
return FALSE;
if (fetch_header)
size = 0;
else {
}
return FALSE;
if (ret > 0) {
}
return ret >= 0;
}
static const char **get_fields_array(const char *fields)
{
const char **field_list, **field;
while (*fields == ' ')
fields++;
if (*fields == '(')
fields++;
/* array ends at ")" element */
}
return field_list;
}
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;
}
{
return TRUE;
}
}
}
return FALSE;
}
}
struct fetch_header_field_context *ctx)
{
struct message_header_parser_ctx *hdr_ctx;
struct message_header_line *hdr;
/* 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 message_size *size,
const struct imap_fetch_body_data *body,
const char *header_section)
{
struct fetch_header_field_context hdr_ctx;
const char *str;
int failed;
/* HEADER, MIME, HEADER.FIELDS (list), HEADER.FIELDS.NOT (list) */
/* all headers */
return FALSE;
}
/* 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 */
} else {
}
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;
return FALSE;
}
/* Find message_part for section (eg. 1.3.4) */
static const struct message_part *
const char **section)
{
const struct message_part *part;
const char *path;
unsigned int num;
return NULL;
/* get part number */
num = 0;
return NULL;
path++;
}
if (*path == '.')
path++;
/* find the part */
} else {
/* only 1 allowed with non-multipart messages */
if (num != 1)
return NULL;
}
}
}
return part;
}
/* fetch BODY[1.2] or BODY[1.2.TEXT] */
const struct imap_fetch_body_data *body,
{
const char *str;
size = 0;
else {
}
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;
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;
}