imap-fetch-body-section.c revision e015e2f7e7f48874495f9df8b0dd192b7ffcb5cc
/* 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;
}
const struct imap_fetch_body_data *body,
{
const char *str;
return FALSE;
if (ret > 0) {
}
/* Input stream gave less data then we expected. Two choices
here: either we fill the missing data with spaces or we
disconnect the client.
We shouldn't really ever get here. One reason is if mail
was deleted from NFS server while we were reading it.
Another is some temporary disk error.
If we filled the missing data the client could cache it,
and if it was just a temporary error the message would be
permanently left corrupted in client's local cache. So, we
disconnect the client and hope that next try works. */
return FALSE;
}
return TRUE;
}
/* fetch BODY[] or BODY[TEXT] */
const struct imap_fetch_body_data *body,
{
return FALSE;
if (fetch_header)
&body_size);
}
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;
}
}
else {
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. */
continue;
break;
break;
}
break;
if (!hdr->no_newline) {
break;
}
}
/* FIXME: We'll just always add the end of headers mark now.
mail-storage should rather include it in the header stream..
however, not much of a problem since all non-broken mails have it.
Also, Netscape 4.x seems to require this or it won't show the
mail.. So if we do make this as RFC says, we'll need to add
netscape-workaround. */
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 */
}
/* 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 */
if (!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)
}
/* if remainder of path is a number or "HEADER",
}
}
return TRUE;
}
const struct imap_fetch_body_data *body)
{
const struct message_part *part;
const char *section;
return FALSE;
/* part doesn't exist */
}
return FALSE;
part->physical_pos +
}
}
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;
}