index-mail-headers.c revision 045aa2f81225ceffbffe71a088dabb8881c65512
/* Copyright (c) 2003-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream.h"
#include "array.h"
#include "buffer.h"
#include "str.h"
#include "message-date.h"
#include "message-parser.h"
#include "message-header-decode.h"
#include "istream-tee.h"
#include "istream-header-filter.h"
#include "imap-envelope.h"
#include "imap-bodystructure.h"
#include "index-storage.h"
#include "index-mail.h"
static const enum message_header_parser_flags hdr_parser_flags =
static const enum message_parser_flags msg_parser_flags =
const struct index_mail_line *l2)
{
int diff;
}
{
const struct index_mail_line *lines;
bool noncontiguous;
/* sort it first so fields are grouped together and ordered by
line number */
/* go through all the header lines we found */
/* matches and header lines are both sorted, all matches
until lines[i] weren't found */
match_idx < match_count) {
/* this header doesn't exist. remember that. */
HEADER_MATCH_FLAG_FOUND) == 0);
NULL, 0);
}
match_idx++;
}
if (match_idx < match_count) {
/* save index to first header line */
j = i + 1;
match_idx++;
}
/* header is already cached */
j = i + 1;
continue;
}
/* buffer contains: { uint32_t line_num[], 0, header texts }
noncontiguous is just a small optimization.. */
buffer_set_used_size(buf, 0);
for (j = i+1; j < count; j++) {
break;
}
if (noncontiguous) {
for (; i < j; i++) {
}
i--;
} else {
}
}
/* this header doesn't exist. remember that. */
HEADER_MATCH_FLAG_FOUND) == 0);
}
}
}
static unsigned int
{
struct mail_cache_field header_field = {
NULL, 0, MAIL_CACHE_FIELD_HEADER, 0,
};
T_BEGIN {
} T_END;
return header_field.idx;
}
{
return TRUE;
return TRUE;
return FALSE;
}
{
const struct mail_cache_field *all_cache_fields;
unsigned int i, count;
pool_datastack_create(), &count);
for (i = 0; i < count; i++) {
continue;
continue;
}
}
struct mailbox_header_lookup_ctx *headers)
{
unsigned int i, field_idx, match_count;
} else {
(HEADER_MATCH_SKIP_COUNT-1)) == 0);
if (mail->header_match_value == 0) {
/* wrapped, we'll have to clear the buffer */
}
}
}
}
}
}
/* register also all the other headers that exist in cache file */
T_BEGIN {
} T_END;
/* if we want sent date, it doesn't mean that we also want to cache
Date: header. if we have Date field's index set at this point we
know that we want it. otherwise add it and remember that we don't
want it cached. */
if (field_idx < match_count &&
/* cache Date: header */
/* parse Date: header, but don't cache it. */
}
}
{
const unsigned int cache_field_envelope =
}
}
struct message_header_line *hdr,
struct index_mail *mail)
{
data->parse_line_num++;
if (data->save_bodystructure_header) {
}
if (data->save_envelope) {
}
/* end of headers */
T_BEGIN {
} T_END;
return;
}
T_BEGIN {
const char *cache_field_name =
} T_END;
}
/* we don't want this header. */
return;
}
/* beginning of a line. add the header name. */
/* remember that we saw this header so we don't add it to
cache as nonexistent. */
}
if (!hdr->no_newline)
}
}
static void
struct message_header_line *hdr,
struct index_mail *mail)
{
}
static void
struct index_mail *mail)
{
}
struct istream *
{
/* we're doing everything for now, figure out later if we want to
save them. */
return input2;
}
{
struct message_part *parts;
} else {
data->parser_ctx =
}
}
struct mailbox_header_lookup_ctx *headers)
{
return -1;
/* initialize bodystructure parsing in case we read the whole
message. */
mail);
} else {
/* just read the header */
}
return 0;
}
static void
struct index_mail *mail)
{
}
{
const unsigned int cache_field_envelope =
struct mailbox_header_lookup_ctx *header_ctx;
cache_field_envelope) > 0) {
return 0;
}
return -1;
}
/* we got the headers from cache - parse them to get the
envelope */
}
return 0;
}
{
const unsigned char *data;
if (data[i] == '\n') {
if (i+1 == size ||
return i - pos;
}
}
}
unsigned int field_idx)
{
unsigned int count;
return -1;
}
{
const unsigned char *p = *data;
size_t i;
for (i = 0; i < len; i++) {
if (p[i] == ':')
break;
}
if (i == len)
return FALSE;
for (i++; i < len; i++) {
if (!IS_LWSP(p[i]))
break;
}
*data = p + i;
return TRUE;
}
static const char *const *
{
ARRAY_DEFINE(header_values, const char *);
const struct index_mail_line *lines;
const unsigned int *line_idx;
const char *value;
unsigned int i, lines_count, first_line_idx;
for (i = first_line_idx; i < lines_count; i++) {
break;
/* skip header: and drop ending LF */
value_end--;
value_end - value_start);
}
}
(void)array_append_space(&header_values);
return array_idx(&header_values, 0);
}
static int
const char *const **value_r)
{
struct mailbox_header_lookup_ctx *headers_ctx;
unsigned char *data;
unsigned int field_idx;
int ret;
ARRAY_DEFINE(header_values, const char *);
/* not in cache / error - first see if it's already parsed */
/* parse */
headers);
if (ret < 0)
return -1;
}
/* not found */
return 0;
}
return 0;
}
if (len == 0) {
/* cached as nonexistent. */
return 0;
}
/* cached. skip "header name: " parts in dest. */
for (i = 0; i < len; i++) {
if (data[i] == ':') {
/* @UNSAFE */
i += len + 1;
}
}
(void)array_append_space(&header_values);
return 0;
}
{
char *new_str;
unsigned int i, j;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] == '\n')
break;
}
if (str[i] == '\0')
return 0;
/* @UNSAFE */
for (j = i; str[i] != '\0'; i++) {
if (str[i] == '\n') {
new_str[j++] = ' ';
i++;
if (str[i] == '\0')
break;
/* corrupted */
return -1;
}
} else {
}
}
new_str[j] = '\0';
return 0;
}
static int
unsigned int max_count)
{
const char **decoded_list, *input;
unsigned int i, count;
for (i = 0; i < count; i++) {
str_truncate(str, 0);
/* unfold all lines into a single line */
return -1;
/* decode MIME encoded-words. decoding may also add new LFs. */
if (message_header_decode_utf8((const unsigned char *)input,
decoded_list[i] = input;
}
*_list = decoded_list;
return 0;
}
bool decode_to_utf8, const char *const **value_r)
{
int ret, i;
for (i = 0; i < 2; i++) {
return -1;
return 0;
T_BEGIN {
} T_END;
if (ret < 0) {
"Broken header %s for mail UID %u",
}
}
return ret;
}
bool decode_to_utf8, const char **value_r)
{
const char *const *list;
int ret, i;
for (i = 0; i < 2; i++) {
return -1;
ret = 0;
break;
}
T_BEGIN {
} T_END;
if (ret < 0) {
"Broken header %s for mail UID %u",
}
}
}
{
}
struct mailbox_header_lookup_ctx *headers,
{
/* we have to parse the header. */
return -1;
}
return 0;
}
/* not in cache / error */
return -1;
return 0;
}