mail-cache-lookup.c revision 6a7f64562ddd0dd2fec755ec4e9c9afde8e85cf1
/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "str.h"
#include "mail-cache-private.h"
#include <stdlib.h>
#define CACHE_PREFETCH 1024
const struct mail_cache_record **rec_r)
{
const struct mail_cache_record *rec;
/* we don't know yet how large the record is, so just guess */
return -1;
return -1;
}
return -1;
}
/* larger than we guessed. map the rest of the record. */
return -1;
}
return -1;
}
return 0;
}
{
struct mail_index_map *map;
const void *data;
/* no cache offsets */
return 0;
}
if (offset == 0)
return 0;
i_unreached();
return offset;
}
static int
{
int i, ret;
if (offset == 0)
return 0;
/* reset_id must match file_seq or the offset is for a different cache
file. if this happens, try if reopening the cache helps. if not,
it was probably for an old cache file that's already lost by now. */
i = 0;
return 0;
/* we're probably compressing */
return 0;
}
/* error / we already have the latest file open */
return ret;
}
}
return 1;
}
{
unsigned int i, count;
for (i = 0; i < count; i++) {
return TRUE;
}
return FALSE;
}
struct mail_cache_lookup_iterate_ctx *ctx_r)
{
int ret;
/* look up the first offset */
if (ret <= 0) {
}
}
}
static int
{
/* end of this record list. check newly appended data. */
if (ctx->appends_checked ||
return 0;
}
/* look up the next record */
"record list is circular");
return -1;
}
return -1;
return 1;
}
struct mail_cache_iterate_field *field_r)
{
unsigned int field_idx;
unsigned int data_size;
int ret;
"record has invalid size");
return -1;
}
return ret;
}
/* return the next field */
/* new field, have to re-read fields header to figure
out its size. don't do this if we're compressing. */
if (mail_cache_header_fields_read(cache) < 0)
return -1;
}
"field index too large (%u >= %u)",
return -1;
}
/* field reading might have re-mmaped the file and
caused rec pointer to break. need to get it again. */
return -1;
}
if (data_size == (unsigned int)-1 &&
/* variable size field. get its size from the file. */
}
"record continues outside its allocated size");
return -1;
}
/* each record begins from 32bit aligned position */
return 1;
}
{
struct mail_cache_lookup_iterate_ctx iter;
struct mail_cache_iterate_field field;
int ret;
if (++view->cached_exists_value == 0) {
/* wrapped, we'll have to clear the buffer */
}
}
return ret;
}
static bool
{
}
unsigned int field)
{
return 0;
/* FIXME: we should discard the cache if view has been synced */
return -1;
}
}
{
}
static int
unsigned int field_idx, unsigned int field_size,
{
struct mail_cache_iterate_field field;
const unsigned char *src;
unsigned char *dest;
unsigned int i;
int ret;
/* make sure all bits are cleared first */
continue;
/* merge all bits */
}
}
{
const struct mail_cache_field *field_def;
struct mail_cache_lookup_iterate_ctx iter;
struct mail_cache_iterate_field field;
int ret;
if (ret <= 0)
return ret;
/* the field should exist */
dest_buf);
}
/* return the first one that's found. if there are multiple
they're all identical. */
break;
}
}
return ret;
}
struct header_lookup_data {
};
struct header_lookup_line {
struct header_lookup_data *data;
};
struct header_lookup_context {
struct mail_cache_view *view;
};
enum {
};
const struct mail_cache_iterate_field *field)
{
struct header_lookup_line hdr_line;
struct header_lookup_data *hdr_data;
unsigned int i, lines_count;
/* data = { line_nums[], 0, "headers" } */
if (lines[i] == 0)
break;
}
lines_count = i;
for (i = 0; i < lines_count; i++) {
}
}
{
}
static int
unsigned int fields_count)
{
struct mail_cache_lookup_iterate_ctx iter;
struct mail_cache_iterate_field field;
struct header_lookup_context ctx;
struct header_lookup_line *lines;
int ret;
if (fields_count == 0)
return 1;
/* update the decision state regardless of whether the fields
actually exist or not. */
for (i = 0; i < fields_count; i++)
/* mark all the fields we want to find. */
for (i = 0; i < fields_count; i++) {
return 0;
if (field_idxs[i] > max_field)
max_field = field_idxs[i];
}
/* lookup the fields */
/* a) don't want it, b) duplicate */
} else {
}
}
if (ret < 0)
return -1;
/* check that all fields were found */
for (i = 0; i <= max_field; i++) {
if (field_state[i] == HDR_FIELD_STATE_WANT)
return 0;
}
/* we need to return headers in the order they existed originally.
we can do this by sorting the messages by their line numbers. */
/* then start filling dest buffer from the headers */
for (i = 0; i < count; i++) {
/* find the end of the (multiline) header */
if (*p == '\n' &&
p++;
break;
}
}
/* if there are more lines for this header, the following lines
continue after this one. so skip this line. */
}
return 1;
}
unsigned int fields_count)
{
int ret;
);
return ret;
}