mail-cache-lookup.c revision efe78d3ba24fc866af1c79b9223dc0809ba26cad
395N/A/* Copyright (c) 2003-2016 Dovecot authors, see the included COPYING file */ 3177N/A /* records are always 32-bit aligned */ 395N/A /* we don't know yet how large the record is, so just guess */ 395N/A /* larger than we guessed. map the rest of the record. */ /* 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. */ /* we're probably compressing */ /* error / we already have the latest file open */ /* looping happens only in rare error conditions, so it's enough if we just catch it eventually. we do this by checking if we've seen more record data than possible in the accessed file area. */ /* look up the first offset */ /* end of this record list. check newly appended data. */ /* check data still in memory. this works for recent mails even with INDEX=MEMORY */ /* check data already written to cache file */ /* look up the next record */ "record list is circular");
"record has invalid size");
/* 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. */ "field index too large (%u >= %u)",
/* field reading might have re-mmaped the file and caused rec pointer to break. need to get it again. */ /* variable size field. get its size from the file. */ "record continues outside its allocated size");
/* each record begins from 32bit aligned position */ /* wrapped, we'll have to clear the buffer */ /* FIXME: we should discard the cache if view has been synced */ const unsigned char *
src;
/* make sure all bits are cleared first */ /* the field should exist */ /* return the first one that's found. if there are multiple they're all identical. */ const unsigned char *
data;
/* data = { line_nums[], 0, "headers" } */ /* update the decision state regardless of whether the fields actually exist or not. */ /* mark all the fields we want to find. */ /* a) don't want it, b) duplicate */ /* check that all fields were found */ /* 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 */ (p+
1 ==
end || (p[
1] !=
' ' && p[
1] !=
'\t'))) {
/* if there are more lines for this header, the following lines continue after this one. so skip this line. */ return "Cache file is unusable";
"Index reset_id=%u doesn't match cache reset_id=%u",
"Mail has other cached fields, reset_id=%u",
reset_id);
/* find the newest mail that has anything in cache */ "Mail not cached, highest cached seq=%u uid=%u: " "Index reset_id=%u doesn't match cache reset_id=%u",
"Mail not cached, highest cached seq=%u uid=%u: reset_id=%u",