mail-cache-lookup.c revision fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_cache_get_header_fields_str(struct mail_cache *cache, unsigned int idx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned char *buf;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen offset = mail_cache_offset_to_uint32(cache->hdr->header_offsets[idx]);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (mail_cache_map(cache, offset, CACHE_PREFETCH) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (offset + sizeof(data_size) > cache->mmap_length) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_corrupted(cache, "Header %u points outside file",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcpy(&data_size, buf + offset, sizeof(data_size));
56f45b3f3ae20e5c933701f4657dda5ef1916855Timo Sirainen if (data_size + sizeof(data_size) > CACHE_PREFETCH) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (mail_cache_map(cache, offset, data_size) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (offset + data_size > cache->mmap_length) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_corrupted(cache, "Header %u points outside file",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *const *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_cache_split_header(struct mail_cache *cache, const char *header)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buf = buffer_create_dynamic(cache->split_header_pool, 32, (size_t)-1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str = p_strdup(cache->split_header_pool, *tmp);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *const *mail_cache_get_header_fields(struct mail_cache_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int idx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *str;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* t_strsplit() is a bit slow, so we cache it */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (cache->hdr->header_offsets[idx] != cache->split_offsets[idx]) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < MAIL_CACHE_HEADERS_COUNT; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str = mail_cache_get_header_fields_str(cache, i);
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainenmail_cache_get_record(struct mail_cache *cache, uint32_t offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (offset + sizeof(*cache_rec) > cache->mmap_length) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_corrupted(cache, "record points outside file");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_corrupted(cache, "invalid record size");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_set_corrupted(cache, "record points outside file");
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenint mail_cache_lookup_offset(struct mail_cache_view *view, uint32_t seq,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen for (i = 0; i < 2; i++) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen ret = mail_index_lookup_full(view->view, seq, &map, &rec);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (map->hdr->cache_file_seq == view->cache->hdr->file_seq) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if ((ret = mail_cache_reopen(view->cache)) <= 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_cache_lookup(struct mail_cache_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_cache_transaction_autocommit(view, seq, fields) < 0)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (mail_cache_lookup_offset(view, seq, &offset, FALSE) <= 0)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return mail_cache_get_record(view->cache, offset, TRUE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_cache_get_fields(struct mail_cache_view *view, uint32_t seq)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen cache_rec = mail_cache_get_record(view->cache,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int cache_get_field(struct mail_cache *cache,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned char *buf;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0, mask = 1; i < 31; i++, mask <<= 1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* all records are at least 32bit. we have to check this
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen before getting data_size. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Record continues outside it's allocated size");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcpy(&data_size, buf + offset, sizeof(data_size));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen next_offset = offset + ((data_size + 3) & ~3);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Record continues outside it's allocated size");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Field size is 0");
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainenint mail_cache_lookup_field(struct mail_cache_view *view, uint32_t seq,
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen mail_cache_handle_decisions(view, seq, field);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen cache_rec = mail_cache_lookup(view, seq, field);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return cache_get_field(view->cache, cache_rec, field,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen cache_rec = mail_cache_get_record(view->cache,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_cache_lookup_string_field(struct mail_cache_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert((field & MAIL_CACHE_STRING_MASK) != 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_cache_lookup_field(view, seq, field, &data, &size))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "String field %x doesn't end with NUL", field);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_cache_copy_fixed_field(struct mail_cache_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert((field & MAIL_CACHE_FIXED_MASK) != 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_cache_lookup_field(view, seq, field, &data, &size))