Beispiel #1
0
static bool imapc_mail_get_cached_guid(struct mail *_mail)
{
	struct index_mail *imail = (struct index_mail *)_mail;
	const enum index_cache_field cache_idx =
		imail->ibox->cache_fields[MAIL_CACHE_GUID].idx;
	string_t *str;

	if (imail->data.guid != NULL) {
		if (mail_cache_field_can_add(_mail->transaction->cache_trans,
					     _mail->seq, cache_idx)) {
			/* GUID was prefetched - add to cache */
			index_mail_cache_add_idx(imail, cache_idx,
				imail->data.guid, strlen(imail->data.guid)+1);
		}
		return TRUE;
	}

	str = str_new(imail->mail.data_pool, 64);
	if (mail_cache_lookup_field(_mail->transaction->cache_view,
				    str, imail->mail.mail.seq, cache_idx) > 0) {
		imail->data.guid = str_c(str);
		return TRUE;
	}
	return FALSE;
}
static void index_mail_parse_finish_imap_envelope(struct index_mail *mail)
{
	struct mail *_mail = &mail->mail.mail;
	const unsigned int cache_field_envelope =
		mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
	string_t *str;

	str = str_new(mail->mail.data_pool, 256);
	imap_envelope_write_part_data(mail->data.envelope_data, str);
	mail->data.envelope = str_c(str);

	if (mail_cache_field_can_add(_mail->transaction->cache_trans,
				     _mail->seq, cache_field_envelope)) {
		index_mail_cache_add_idx(mail, cache_field_envelope,
					 str_data(str), str_len(str));
	}
}
Beispiel #3
0
static bool
index_mail_want_cache(struct index_mail *mail, enum index_cache_field field)
{
	enum mail_fetch_field fetch_field;
	unsigned int cache_field;

	switch (field) {
	case MAIL_CACHE_SENT_DATE:
		fetch_field = MAIL_FETCH_DATE;
		break;
	case MAIL_CACHE_RECEIVED_DATE:
		fetch_field = MAIL_FETCH_RECEIVED_DATE;
		break;
	case MAIL_CACHE_SAVE_DATE:
		fetch_field = MAIL_FETCH_SAVE_DATE;
		break;
	case MAIL_CACHE_VIRTUAL_FULL_SIZE:
		fetch_field = MAIL_FETCH_VIRTUAL_SIZE;
		break;
	case MAIL_CACHE_PHYSICAL_FULL_SIZE:
		fetch_field = MAIL_FETCH_PHYSICAL_SIZE;
		break;
	default:
		i_unreached();
	}

	if ((mail->data.dont_cache_fetch_fields & fetch_field) != 0)
		return FALSE;

	cache_field = mail->ibox->cache_fields[field].idx;
	if ((mail->data.cache_fetch_fields & fetch_field) != 0) {
		return mail_cache_field_can_add(mail->trans->cache_trans,
						mail->data.seq, cache_field);
	} else {
		return mail_cache_field_want_add(mail->trans->cache_trans,
						 mail->data.seq, cache_field);
	}
}
static void index_mail_parse_header_finish(struct index_mail *mail)
{
	struct mail *_mail = &mail->mail.mail;
	const struct index_mail_line *lines;
	const unsigned char *header, *data;
	const uint8_t *match;
	buffer_t *buf;
	size_t data_size;
	unsigned int i, j, count, match_idx, match_count;
	bool noncontiguous;

	/* sort it first so fields are grouped together and ordered by
	   line number */
	array_sort(&mail->header_lines, header_line_cmp);

	lines = array_get(&mail->header_lines, &count);
	match = array_get(&mail->header_match, &match_count);
	header = buffer_get_data(mail->header_data, NULL);
	buf = buffer_create_dynamic(pool_datastack_create(), 256);

	/* go through all the header lines we found */
	for (i = match_idx = 0; i < count; i = j) {
		/* matches and header lines are both sorted, all matches
		   until lines[i] weren't found */
		while (match_idx < lines[i].field_idx &&
		       match_idx < match_count) {
			if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
			    mail_cache_field_can_add(_mail->transaction->cache_trans,
						     _mail->seq, match_idx)) {
				/* this header doesn't exist. remember that. */
				i_assert((match[match_idx] &
					  HEADER_MATCH_FLAG_FOUND) == 0);
				index_mail_cache_add_idx(mail, match_idx,
							 "", 0);
			}
			match_idx++;
		}

		if (match_idx < match_count) {
			/* save index to first header line */
			j = i + 1;
			array_idx_set(&mail->header_match_lines, match_idx, &j);
			match_idx++;
		}

		if (!mail_cache_field_can_add(_mail->transaction->cache_trans,
					      _mail->seq, lines[i].field_idx)) {
			/* header is already cached */
			j = i + 1;
			continue;
		}

		/* buffer contains: { uint32_t line_num[], 0, header texts }
		   noncontiguous is just a small optimization.. */
		buffer_set_used_size(buf, 0);
		buffer_append(buf, &lines[i].line_num,
			      sizeof(lines[i].line_num));

		noncontiguous = FALSE;
		for (j = i+1; j < count; j++) {
			if (lines[j].field_idx != lines[i].field_idx)
				break;

			if (lines[j].start_pos != lines[j-1].end_pos)
				noncontiguous = TRUE;
			buffer_append(buf, &lines[j].line_num,
				      sizeof(lines[j].line_num));
		}
		buffer_append_zero(buf, sizeof(uint32_t));

		if (noncontiguous) {
			for (; i < j; i++) {
				buffer_append(buf, header + lines[i].start_pos,
					      lines[i].end_pos -
					      lines[i].start_pos);
			}
			i--;
		} else {
			buffer_append(buf, header + lines[i].start_pos,
				      lines[j-1].end_pos - lines[i].start_pos);
		}

		data = buffer_get_data(buf, &data_size);
		index_mail_cache_add_idx(mail, lines[i].field_idx,
					 data, data_size);
	}

	for (; match_idx < match_count; match_idx++) {
		if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
		    mail_cache_field_can_add(_mail->transaction->cache_trans,
					     _mail->seq, match_idx)) {
			/* this header doesn't exist. remember that. */
			i_assert((match[match_idx] &
				  HEADER_MATCH_FLAG_FOUND) == 0);
			index_mail_cache_add_idx(mail, match_idx, "", 0);
		}
	}

	mail->data.dont_cache_field_idx = UINT_MAX;
}
Beispiel #5
0
static void
index_mail_body_parsed_cache_bodystructure(struct index_mail *mail,
					   enum index_cache_field field)
{
	struct index_mail_data *data = &mail->data;
	unsigned int cache_field_parts =
		mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
	unsigned int cache_field_body =
		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
	unsigned int cache_field_bodystructure =
		mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
	enum mail_cache_decision_type dec;
	string_t *str;
	bool bodystructure_cached = FALSE;
	bool plain_bodystructure = FALSE;
	bool cache_bodystructure, cache_body;

	if ((data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0) {
		if (data->messageparts_saved_to_cache ||
		    mail_cache_field_exists(mail->trans->cache_view, data->seq,
					    cache_field_parts) > 0) {
			/* cached it as flag + message_parts */
			plain_bodystructure = TRUE;
		}
	}

	if (!data->parsed_bodystructure)
		return;

	/* If BODY is fetched first but BODYSTRUCTURE is also wanted, we don't
	   normally want to first cache BODY and then BODYSTRUCTURE. So check
	   the wanted_fields also in here. */
	if (plain_bodystructure)
		cache_bodystructure = FALSE;
	else if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE ||
		 (mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
		cache_bodystructure =
			mail_cache_field_can_add(mail->trans->cache_trans,
				data->seq, cache_field_bodystructure);
	} else {
		cache_bodystructure =
			mail_cache_field_want_add(mail->trans->cache_trans,
				data->seq, cache_field_bodystructure);
	}
	if (cache_bodystructure) {
		str = str_new(mail->data_pool, 128);
		imap_bodystructure_write(data->parts, str, TRUE);
		data->bodystructure = str_c(str);

		index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODYSTRUCTURE,
				     str_c(str), str_len(str)+1);
		bodystructure_cached = TRUE;
	} else {
		bodystructure_cached =
			mail_cache_field_exists(mail->trans->cache_view,
				data->seq, cache_field_bodystructure) > 0;
	}

	/* normally don't cache both BODY and BODYSTRUCTURE, but do it
	   if BODY is forced to be cached */
	dec = mail_cache_field_get_decision(mail->mail.mail.box->cache,
					    cache_field_body);
	if (plain_bodystructure ||
	    (bodystructure_cached &&
	     (dec != (MAIL_CACHE_DECISION_FORCED | MAIL_CACHE_DECISION_YES))))
		cache_body = FALSE;
	else if (field == MAIL_CACHE_IMAP_BODY) {
		cache_body =
			mail_cache_field_can_add(mail->trans->cache_trans,
				data->seq, cache_field_body);
	} else {
		cache_body =
			mail_cache_field_want_add(mail->trans->cache_trans,
				data->seq, cache_field_body);
	}

	if (cache_body) {
		str = str_new(mail->data_pool, 128);
		imap_bodystructure_write(data->parts, str, FALSE);
		data->body = str_c(str);

		index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODY,
				     str_c(str), str_len(str)+1);
	}
}