mail-cache-fields.c revision a04b6515c20b431294626400e173d81f3d25889b
/* Copyright (c) 2004-2007 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "buffer.h"
#include "hash.h"
#include "file-cache.h"
#include "read-full.h"
#include "write-full.h"
#include "mmap-util.h"
#include "mail-cache-private.h"
#include <stddef.h>
{
switch (type) {
case MAIL_CACHE_FIELD_BITMASK:
return TRUE;
case MAIL_CACHE_FIELD_STRING:
case MAIL_CACHE_FIELD_HEADER:
return FALSE;
case MAIL_CACHE_FIELD_COUNT:
break;
}
i_unreached();
return FALSE;
}
{
switch (type & ~MAIL_CACHE_DECISION_FORCED) {
case MAIL_CACHE_DECISION_NO:
case MAIL_CACHE_DECISION_TEMP:
case MAIL_CACHE_DECISION_YES:
return TRUE;
default:
return FALSE;
}
}
{
return -1;
}
return -1;
}
return 0;
}
struct mail_cache_field *fields,
unsigned int fields_count)
{
void *orig_key, *orig_value;
char *name;
unsigned int new_idx;
unsigned int i, j;
for (i = 0; i < fields_count; i++) {
&orig_key, &orig_value)) {
POINTER_CAST_TO(orig_value, unsigned int);
fields[i].field_size);
continue;
}
/* check if the same header is being registered in the
same field array */
for (j = 0; j < i; j++) {
break;
}
}
if (j == i)
}
return;
/* @UNSAFE */
for (i = 0; i < fields_count; i++) {
continue;
/* new index - save it */
}
}
unsigned int
{
void *orig_key, *orig_value;
&orig_key, &orig_value))
return POINTER_CAST_TO(orig_value, unsigned int);
else
return (unsigned int)-1;
}
const struct mail_cache_field *
unsigned int *count_r)
{
struct mail_cache_field *list;
unsigned int i;
(void)mail_cache_open_and_verify(cache);
for (i = 0; i < cache->fields_count; i++) {
}
return list;
}
{
const struct mail_cache_header_fields *field_hdr;
unsigned int next_count = 0;
bool invalidate = FALSE;
int ret;
if (MAIL_CACHE_IS_UNUSABLE(cache)) {
*offset_r = 0;
return 0;
}
/* find the latest header */
offset = 0;
while (next_offset != 0) {
if (next_offset == offset) {
"next_offset in field header loops");
return -1;
}
invalidate = TRUE;
sizeof(*field_hdr)) < 0)
return -1;
} else {
/* if we need to follow multiple offsets to get to
the last one, it's faster to just pread() the file
instead of going through cache */
sizeof(tmp_field_hdr), offset);
if (ret < 0) {
return -1;
}
if (ret == 0) {
"next_offset points outside file");
return -1;
}
}
next_count++;
}
if (offset == 0) {
return -1;
}
if (map) {
/* if this isn't the first header in file and we hadn't
read this before, we can't trust that the cached
data is valid */
}
return -1;
}
return 0;
}
{
struct mail_cache_field field;
void *orig_key, *orig_value;
unsigned int fidx, new_fields_count;
return -1;
if (offset == 0) {
/* no fields - the file is empty */
return 0;
}
"field header points outside file");
return -1;
}
/* check the fixed size of the header. name[] has to be checked
separately */
return -1;
}
if (new_fields_count != 0) {
sizeof(unsigned int),
new_fields_count * sizeof(unsigned int));
} else {
}
/* clear the old mapping */
for (i = 0; i < cache->fields_count; i++)
for (i = 0; i < field_hdr->fields_count; i++) {
"field header names corrupted");
return -1;
}
if (types[i] > MAIL_CACHE_FIELD_COUNT) {
return -1;
}
if (!field_decision_is_valid(decisions[i])) {
"field decision type corrupted");
return -1;
}
&orig_key, &orig_value)) {
/* already exists, see if decision can be updated */
decisions[i];
}
return -1;
} else {
}
"Duplicated field in header: %s", names);
return -1;
}
/* update last_used if it's newer than ours */
/* time to drop this field. don't bother dropping
fields that have never been used. */
}
names = p + 1;
}
return 0;
}
{
const void *data;
unsigned int i, field;
/* copy the existing fields */
for (i = 0; i < cache->file_fields_count; i++) {
}
if (!add_new)
return;
/* copy newly wanted fields */
for (i = 0; i < cache->fields_count; i++) {
if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
}
}
}
{
const int *data;
unsigned int i, field;
/* copy the existing fields */
for (i = 0; i < cache->file_fields_count; i++) {
}
if (!add_new)
return;
/* copy newly wanted fields */
for (i = 0; i < cache->fields_count; i++) {
if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
}
}
}
{
int ret = 0;
if (mail_cache_header_fields_read(cache) < 0 ||
return -1;
sizeof(uint32_t));
if (ret == 0) {
dec_offset = offset +
if (ret == 0) {
for (i = 0; i < cache->file_fields_count; i++)
}
}
if (ret == 0)
return ret;
}
{
int ret;
);
return ret;
}
return -1;
);
if (mail_cache_unlock(cache) < 0)
ret = -1;
return ret;
}
{
struct mail_cache_header_fields hdr;
unsigned int field;
const char *name;
uint32_t i;
for (i = 0; i < cache->fields_count; i++) {
/* return newly added fields' last_used as
the current time */
}
if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i))
hdr.fields_count++;
}
/* we have to keep the field order for the existing fields. */
sizeof(uint32_t));
sizeof(uint32_t));
/* add existing fields' names */
for (i = 0; i < cache->file_fields_count; i++) {
}
/* add newly wanted fields' names */
for (i = 0; i < cache->fields_count; i++) {
if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
}
}
}
{
return -1;
if (*offset_r == 0) {
} else {
}
return 0;
}