mail-cache-lookup.c revision 1171f0abf442638bac1827bb24a0b6b8eb682a82
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_cache_get_header_fields_str(struct mail_cache *cache, unsigned int idx)
2cd2518bab14292a67cf8a490b58ab9ef89879daTimo Sirainen const unsigned char *buf;
6ec925f52d04ec8700e47cb005bd7ddc65ac5614Timo Sirainen offset = mail_cache_offset_to_uint32(cache->hdr->header_offsets[idx]);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_cache_map(cache, offset, CACHE_PREFETCH) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (offset + sizeof(data_size) > cache->mmap_length) {
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen mail_cache_set_corrupted(cache, "Header %u points outside file",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen memcpy(&data_size, buf + offset, sizeof(data_size));
5d4c793b4e3dbc07f08daa4465594b1857f80725Timo Sirainen if (data_size + sizeof(data_size) > CACHE_PREFETCH) {
5d4c793b4e3dbc07f08daa4465594b1857f80725Timo Sirainen if (mail_cache_map(cache, offset, data_size) < 0)
5d4c793b4e3dbc07f08daa4465594b1857f80725Timo Sirainen if (offset + data_size > cache->mmap_length) {
5d4c793b4e3dbc07f08daa4465594b1857f80725Timo Sirainen mail_cache_set_corrupted(cache, "Header %u points outside file",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenconst char *const *
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_cache_split_header(struct mail_cache *cache, const char *header)
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen buf = buffer_create_dynamic(cache->split_header_pool, 32, (size_t)-1);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen str = p_strdup(cache->split_header_pool, *tmp);
230ef558135f16a66b86cbe3762524eaa9ae9d81Timo Sirainenconst char *const *mail_cache_get_header_fields(struct mail_cache_view *view,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen unsigned int idx)
e9ac518aaf49a06d976bf7f24ab14a3e2d6d86abTimo Sirainen const char *str;
e9ac518aaf49a06d976bf7f24ab14a3e2d6d86abTimo Sirainen /* t_strsplit() is a bit slow, so we cache it */
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen if (cache->hdr->header_offsets[idx] != cache->split_offsets[idx]) {
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen for (i = 0; i < MAIL_CACHE_HEADERS_COUNT; i++) {
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen str = mail_cache_get_header_fields_str(cache, i);
d03a871a77f8ec36f48f5fea98d810e51b186fdbTimo Sirainenmail_cache_get_record(struct mail_cache *cache, uint32_t offset)
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen if (offset + sizeof(*cache_rec) > cache->mmap_length) {
efc5c69c572e83db7bf7eab5d4698c0ab0d3d886Timo Sirainen mail_cache_set_corrupted(cache, "record points outside file");
efc5c69c572e83db7bf7eab5d4698c0ab0d3d886Timo Sirainen mail_cache_set_corrupted(cache, "invalid record size");
efc5c69c572e83db7bf7eab5d4698c0ab0d3d886Timo Sirainen if (mail_cache_map(cache, offset, cache_rec->size) < 0)
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen if (offset + cache_rec->size > cache->mmap_length) {
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen mail_cache_set_corrupted(cache, "record points outside file");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int mail_cache_lookup_offset(struct mail_cache_view *view, uint32_t seq,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < 2; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_index_lookup_full(view->view, seq, &map, &rec) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (map->hdr->cache_file_seq == view->cache->hdr->file_seq) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if ((ret = mail_cache_reopen(view->cache)) <= 0)
e9ac518aaf49a06d976bf7f24ab14a3e2d6d86abTimo Sirainenmail_cache_lookup(struct mail_cache_view *view, uint32_t seq)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen // FIXME: check transactions too
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_cache_lookup_offset(view, seq, &offset) <= 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return mail_cache_get_record(view->cache, offset);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_cache_get_fields(struct mail_cache_view *view, uint32_t seq)
e1f866daa1bd1a5cd7516f3b19c6f197bcf6cc8aTimo Sirainen cache_rec = mail_cache_get_record(view->cache,
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainenstatic int cache_get_field(struct mail_cache *cache,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen enum mail_cache_field field, buffer_t *dest_buf)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int mask;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0, mask = 1; i < 31; i++, mask <<= 1) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* all records are at least 32bit. we have to check this
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen before getting data_size. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (offset + sizeof(uint32_t) > cache_rec->size) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "Record continues outside it's allocated size");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen memcpy(&data_size, CONST_PTR_OFFSET(cache_rec, offset),
5d46f4d076fc13ae2779c365cf4bd9bda3a5bc69Timo Sirainen prev_offset = offset + ((data_size + 3) & ~3);
28482afc8139462ff9bcc6cedc4936129e8763efTimo Sirainen "Record continues outside it's allocated size");
3a0f9aa9504497e4e47f32df54fbf47fdc7423b6Timo Sirainen "Field size is 0");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenint mail_cache_lookup_field(struct mail_cache_view *view, buffer_t *dest_buf,
43d7e7ce608f5451e4907b5f5c48c00beb265802Timo Sirainen mail_cache_handle_decisions(view, seq, field);
5d46f4d076fc13ae2779c365cf4bd9bda3a5bc69Timo Sirainen return cache_get_field(view->cache, cache_rec, field,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen cache_rec = mail_cache_get_record(view->cache,
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainenint mail_cache_lookup_string_field(struct mail_cache_view *view, string_t *dest,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert((field & MAIL_CACHE_STRING_MASK) != 0);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (!mail_cache_lookup_field(view, dest, seq, field))
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen "String field %x doesn't end with NUL", field);