}
struct header_lookup_data {
- uint32_t offset;
uint32_t data_size;
+ const unsigned char *data;
};
struct header_lookup_line {
uint32_t line_num;
- struct header_lookup_data *data;
+ struct header_lookup_data *data;
};
struct header_lookup_context {
struct mail_cache_view *view;
+ pool_t pool;
ARRAY(struct header_lookup_line) lines;
};
uint32_t data_size = field->size;
struct header_lookup_line hdr_line;
struct header_lookup_data *hdr_data;
- unsigned int i, lines_count;
+ void *data_dup;
+ unsigned int i, lines_count, pos;
/* data = { line_nums[], 0, "headers" } */
for (i = 0; data_size >= sizeof(uint32_t); i++) {
break;
}
lines_count = i;
+ pos = (lines_count+1) * sizeof(uint32_t);
- hdr_data = t_new(struct header_lookup_data, 1);
- hdr_data->offset = field->offset + (lines_count+1) * sizeof(uint32_t);
+ hdr_data = p_new(ctx->pool, struct header_lookup_data, 1);
hdr_data->data_size = data_size;
+ hdr_data->data = data_dup = data_size == 0 ? NULL :
+ p_malloc(ctx->pool, data_size);
+ memcpy(data_dup, CONST_PTR_OFFSET(field->data, pos), data_size);
for (i = 0; i < lines_count; i++) {
hdr_line.line_num = lines[i];
static int
mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest,
uint32_t seq, unsigned int field_idxs[],
- unsigned int fields_count)
+ unsigned int fields_count, pool_t *pool_r)
{
struct mail_cache *cache = view->cache;
struct mail_cache_lookup_iterate_ctx iter;
struct mail_cache_iterate_field field;
struct header_lookup_context ctx;
struct header_lookup_line *lines;
- const void *data;
const unsigned char *p, *start, *end;
uint8_t *field_state;
unsigned int i, count, max_field = 0;
buffer_t *buf;
int ret;
+ *pool_r = NULL;
+
if (fields_count == 0)
return 1;
/* lookup the fields */
memset(&ctx, 0, sizeof(ctx));
ctx.view = view;
+ ctx.pool = *pool_r = pool_alloconly_create("mail cache headers", 1024);
t_array_init(&ctx.lines, 32);
mail_cache_lookup_iter_init(view, seq, &iter);
/* then start filling dest buffer from the headers */
for (i = 0; i < count; i++) {
- ret = mail_cache_map(cache, lines[i].data->offset,
- lines[i].data->data_size, &data);
- if (ret <= 0) {
- if (ret < 0)
- return -1;
-
- mail_cache_set_corrupted(cache,
- "header record unexpectedly points outside file");
- return -1;
- }
- start = data;
+ start = lines[i].data->data;
end = start + lines[i].data->data_size;
/* find the end of the (multiline) header */
/* if there are more lines for this header, the following lines
continue after this one. so skip this line. */
- lines[i].data->offset += hdr_size;
+ lines[i].data->data += hdr_size;
lines[i].data->data_size -= hdr_size;
}
return 1;
uint32_t seq, unsigned int field_idxs[],
unsigned int fields_count)
{
+ pool_t pool;
int ret;
T_BEGIN {
ret = mail_cache_lookup_headers_real(view, dest, seq,
- field_idxs, fields_count);
+ field_idxs, fields_count,
+ &pool);
+ if (pool != NULL)
+ pool_unref(&pool);
} T_END;
return ret;
}