mail-cache-lookup.c revision 45324f1eafa565dbc65e4dd335de9507dead55e6
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn/* Copyright (c) 2003-2014 Dovecot authors, see the included COPYING file */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynint mail_cache_get_record(struct mail_cache *cache, uint32_t offset,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn const void *data;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* records are always 32-bit aligned */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn mail_cache_set_corrupted(cache, "invalid record offset");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* we don't know yet how large the record is, so just guess */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (mail_cache_map(cache, offset, sizeof(*rec) + CACHE_PREFETCH,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (offset + sizeof(*rec) > cache->mmap_length) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn mail_cache_set_corrupted(cache, "record points outside file");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn mail_cache_set_corrupted(cache, "invalid record size");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* larger than we guessed. map the rest of the record. */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if ((ret = mail_cache_map(cache, offset, rec->size, &data)) < 0)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn mail_cache_set_corrupted(cache, "record points outside file");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynuint32_t mail_cache_lookup_cur_offset(struct mail_index_view *view,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn struct mail_cache *cache = mail_index_view_get_index(view)->cache;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn const void *data;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn mail_index_lookup_ext_full(view, seq, cache->ext_id, &map, &data, NULL);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* no cache offsets */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (!mail_index_ext_get_reset_id(view, map, cache->ext_id, reset_id_r))
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynmail_cache_lookup_offset(struct mail_cache *cache, struct mail_index_view *view,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn offset = mail_cache_lookup_cur_offset(view, seq, &reset_id);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* reset_id must match file_seq or the offset is for a different cache
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn file. if this happens, try if reopening the cache helps. if not,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn it was probably for an old cache file that's already lost by now. */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (++i == 2 || reset_id < cache->hdr->file_seq)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* we're probably compressing */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* error / we already have the latest file open */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynbool mail_cache_track_loops(struct mail_cache_loop_track *loop_track,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* looping happens only in rare error conditions, so it's enough if we
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn just catch it eventually. we do this by checking if we've seen
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn more record data than possible in the accessed file area. */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn /* first call */
int ret;
if (ret <= 0) {
return FALSE;
return TRUE;
unsigned int field_idx;
unsigned int data_size;
int ret;
return ret;
int ret;
return ret;
unsigned int field)
const unsigned char *src;
unsigned char *dest;
int ret;
int ret;
if (ret <= 0)
return ret;
dest_buf);
return ret;
struct header_lookup_data {
const unsigned char *data;
struct header_lookup_line {
struct header_lookup_context {
void *data_dup;
if (lines[i] == 0)
lines_count = i;
for (i = 0; i < lines_count; i++) {
int ret;
if (fields_count == 0)
for (i = 0; i < fields_count; i++)
for (i = 0; i < fields_count; i++) {
if (ret < 0)
for (i = 0; i <= max_field; i++) {
for (i = 0; i < count; i++) {
unsigned int fields_count)
int ret;
T_BEGIN {
&pool);
} T_END;
return ret;