index-mail-headers.c revision 2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87
/* Copyright (C) 2003-2006 Timo Sirainen */
#include "lib.h"
#include "istream.h"
#include "array.h"
#include "buffer.h"
#include "str.h"
#include "message-date.h"
#include "message-parser.h"
#include "istream-header-filter.h"
#include "imap-envelope.h"
#include "imap-bodystructure.h"
#include "index-storage.h"
#include "index-mail.h"
#include <stdlib.h>
struct index_header_lookup_ctx {
struct mailbox_header_lookup_ctx ctx;
unsigned int count;
unsigned int *idx;
const char **name;
};
{
int diff;
}
{
struct index_mail_line *lines;
bool noncontiguous;
t_push();
/* 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) {
/* if match[] doesn't have header_match_value,
it belongs to some older header parsing and we
just want to ignore it. */
match_idx) == 0) {
/* this header doesn't exist. remember that. */
}
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. */
}
}
/* set all non-found headers registered in cache */
/* first check that it isn't already added in this session */
if (cache_field < match_count &&
continue;
"hdr.", 4) != 0)
continue;
/* check that it hadn't been added in some older session */
}
t_pop();
}
static unsigned int
{
struct mail_cache_field header_field = {
NULL, 0, MAIL_CACHE_FIELD_HEADER, 0,
};
t_push();
t_pop();
return header_field.idx;
}
struct mailbox_header_lookup_ctx *_headers)
{
struct index_header_lookup_ctx *headers =
(struct index_header_lookup_ctx *)_headers;
size_t i;
struct index_mail_line, 32);
unsigned int, 32);
} else {
}
if (mail->header_match_value == 0) {
/* wrapped, we'll have to clear the buffer */
}
}
}
}
}
}
/* get a list of all currently cached fields. we'll later set those
headers that weren't found to empty. if this list is get later,
it's possible that it has already changed (cache has no permanent
write locks, remember!) and we set some headers to empty even
though they really exist. */
}
{
}
struct message_header_line *hdr,
struct index_mail *mail)
{
const char *cache_field_name;
data->parse_line_num++;
if (data->save_bodystructure_header) {
}
if (data->save_envelope) {
}
/* end of headers */
}
return;
}
t_push();
t_pop();
}
if (field_idx == (unsigned int)-1) {
/* we don't want this field */
return;
}
}
/* first header */
/* we don't need to do anything with this header */
return;
}
}
if (!hdr->no_newline)
}
}
static void
{
}
static void
{
}
struct mailbox_header_lookup_ctx *headers)
{
return -1;
/* initialize bodystructure parsing in case we read the whole
message. */
data->parser_ctx =
mail);
} else {
/* just read the header */
}
return 0;
}
static void
{
}
{
struct mailbox_header_lookup_ctx *header_ctx;
/* we got the headers from cache - parse them to get the
envelope */
}
}
{
const unsigned char *data;
if (data[i] == '\n') {
if (i+1 == size ||
return i - pos;
}
}
}
unsigned int field_idx)
{
unsigned int count;
return -1;
return 0;
return 1;
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 *
{
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);
}
}
return array_idx(&header_values, 0);
}
{
struct mailbox_header_lookup_ctx *headers_ctx;
unsigned char *data;
unsigned int field_idx;
int ret;
/* not in cache / error - first see if it's already parsed */
if (ret != -1) {
}
}
/* parse */
headers);
if (ret < 0)
return NULL;
}
if (len == 0) {
/* cached as non-existing. */
}
/* cached. skip "header name: " parts in dest. */
for (i = 0; i < len; i++) {
if (data[i] == ':') {
/* @UNSAFE */
i += len + 1;
}
}
return array_idx(&header_values, 0);
}
{
}
{
}
struct istream *
struct mailbox_header_lookup_ctx *_headers)
{
struct index_header_lookup_ctx *headers =
(struct index_header_lookup_ctx *)_headers;
/* we have to parse the header. */
return NULL;
}
}
/* not in cache / error */
return NULL;
}
struct mailbox_header_lookup_ctx *
{
NULL, 0, MAIL_CACHE_FIELD_HEADER, 0,
};
struct index_header_lookup_ctx *ctx;
const char *const *name;
const char **sorted_headers;
unsigned int i, count;
count++;
t_push();
/* @UNSAFE: headers need to be sorted for filter stream. */
/* @UNSAFE */
for (i = 0; i < count; i++) {
fields[i] = header_field;
}
/* @UNSAFE */
for (i = 0; i < count; i++) {
}
t_pop();
}
{
struct index_header_lookup_ctx *ctx =
(struct index_header_lookup_ctx *)_ctx;
}