예제 #1
0
void index_mail_free(struct mail *_mail)
{
	struct index_mail *mail = (struct index_mail *)_mail;
	struct mailbox_header_lookup_ctx *headers_ctx =
		(struct mailbox_header_lookup_ctx *)mail->wanted_headers;

	mail->mail.v.close(_mail);

	i_assert(mail->trans->mail_ref_count > 0);
	mail->trans->mail_ref_count--;

	if (mail->header_data != NULL)
		buffer_free(&mail->header_data);
	if (array_is_created(&mail->header_lines))
		array_free(&mail->header_lines);
	if (array_is_created(&mail->header_match))
		array_free(&mail->header_match);
	if (array_is_created(&mail->header_match_lines))
		array_free(&mail->header_match_lines);

	if (headers_ctx != NULL)
		mailbox_header_lookup_unref(&headers_ctx);
	pool_unref(&mail->data_pool);
	pool_unref(&mail->mail.pool);
}
예제 #2
0
static void
mail_log_update_wanted_fields(struct mail *mail, enum mail_log_field fields)
{
	enum mail_fetch_field wanted_fields = 0;
	struct mailbox_header_lookup_ctx *wanted_headers = NULL;
	const char *headers[4];
	unsigned int hdr_idx = 0;

	if ((fields & MAIL_LOG_FIELD_MSGID) != 0)
		headers[hdr_idx++] = "Message-ID";
	if ((fields & MAIL_LOG_FIELD_FROM) != 0)
		headers[hdr_idx++] = "From";
	if ((fields & MAIL_LOG_FIELD_SUBJECT) != 0)
		headers[hdr_idx++] = "Subject";
	if (hdr_idx > 0) {
		i_assert(hdr_idx < N_ELEMENTS(headers));
		headers[hdr_idx] = NULL;
		wanted_headers = mailbox_header_lookup_init(mail->box, headers);
	}

	if ((fields & MAIL_LOG_FIELD_PSIZE) != 0)
		wanted_fields |= MAIL_FETCH_PHYSICAL_SIZE;
	if ((fields & MAIL_LOG_FIELD_VSIZE) != 0)
		wanted_fields |= MAIL_FETCH_VIRTUAL_SIZE;

	mail_add_temp_wanted_fields(mail, wanted_fields, wanted_headers);
	if (wanted_headers != NULL)
		mailbox_header_lookup_unref(&wanted_headers);
}
예제 #3
0
static void index_mail_update_access_parts(struct index_mail *mail)
{
	struct mail *_mail = &mail->mail.mail;
	struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
	struct index_mail_data *data = &mail->data;
	struct mailbox_header_lookup_ctx *header_ctx;
	time_t date;
	uoff_t size;

	if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0)
		(void)index_mail_get_received_date(_mail, &date);
	if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) {
		if (index_mail_get_physical_size(_mail, &size) < 0 &&
		    !IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE))
			data->access_part |= READ_HDR | READ_BODY;
	}

	if (data->access_part == 0 && data->wanted_headers != NULL) {
		/* see if all wanted headers exist in cache */
		if (!imapc_mail_has_headers_in_cache(mail, data->wanted_headers))
			data->access_part |= PARSE_HDR;
	}
	if (data->access_part == 0 &&
	    (data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) {
		/* the common code already checked this partially,
		   but we need a guaranteed correct answer */
		header_ctx = mailbox_header_lookup_init(_mail->box,
							imap_envelope_headers);
		if (!imapc_mail_has_headers_in_cache(mail, header_ctx))
			data->access_part |= PARSE_HDR;
		mailbox_header_lookup_unref(&header_ctx);
	}
}
예제 #4
0
int dsync_mail_get_hdr_hash(struct mail *mail, const char **hdr_hash_r)
{
	struct istream *hdr_input, *input;
	struct mailbox_header_lookup_ctx *hdr_ctx;
	struct md5_context md5_ctx;
	unsigned char md5_result[MD5_RESULTLEN];
	const unsigned char *data;
	size_t size;
	int ret = 0;

	hdr_ctx = mailbox_header_lookup_init(mail->box, hashed_headers);
	ret = mail_get_header_stream(mail, hdr_ctx, &hdr_input);
	mailbox_header_lookup_unref(&hdr_ctx);
	if (ret < 0)
		return -1;

	input = i_stream_create_lf(hdr_input);

	md5_init(&md5_ctx);
	while (!i_stream_is_eof(input)) {
		if (i_stream_read_data(input, &data, &size, 0) == -1)
			break;
		if (size == 0)
			break;
		md5_update(&md5_ctx, data, size);
		i_stream_skip(input, size);
	}
	if (input->stream_errno != 0)
		ret = -1;
	i_stream_unref(&input);

	md5_final(&md5_ctx, md5_result);
	*hdr_hash_r = binary_to_hex(md5_result, sizeof(md5_result));
	return ret;
}
예제 #5
0
static void virtual_mail_free(struct mail *mail)
{
	struct virtual_mail *vmail = (struct virtual_mail *)mail;
	struct mail **mails;
	unsigned int i, count;

	mails = array_get_modifiable(&vmail->backend_mails, &count);
	for (i = 0; i < count; i++)
		mail_free(&mails[i]);
	array_free(&vmail->backend_mails);

	if (vmail->wanted_headers != NULL)
		mailbox_header_lookup_unref(&vmail->wanted_headers);

	pool_unref(&vmail->imail.data_pool);
	pool_unref(&vmail->imail.mail.pool);
}
예제 #6
0
static int
imapc_mail_get_headers(struct mail *_mail, const char *field,
		       bool decode_to_utf8, const char *const **value_r)
{
	struct mailbox_header_lookup_ctx *headers;
	const char *header_names[2];
	struct istream *input;
	int ret;

	header_names[0] = field;
	header_names[1] = NULL;
	headers = mailbox_header_lookup_init(_mail->box, header_names);
	ret = mail_get_header_stream(_mail, headers, &input);
	mailbox_header_lookup_unref(&headers);
	if (ret < 0)
		return -1;
	/* the header should cached now. */
	return index_mail_get_headers(_mail, field, decode_to_utf8, value_r);
}
예제 #7
0
struct mail *
virtual_mail_set_backend_mail(struct mail *mail,
			      struct virtual_backend_box *bbox)
{
	struct virtual_mail *vmail = (struct virtual_mail *)mail;
	struct mailbox_transaction_context *backend_trans;
	struct mailbox_header_lookup_ctx *backend_headers;

	backend_trans = virtual_transaction_get(mail->transaction, bbox->box);

	backend_headers = vmail->wanted_headers == NULL ? NULL :
		mailbox_header_lookup_init(bbox->box,
					   vmail->wanted_headers->headers);
	vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
					 backend_headers);
	if (backend_headers != NULL)
		mailbox_header_lookup_unref(&backend_headers);
	array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
	return vmail->backend_mail;
}
예제 #8
0
static struct mail_raw *mail_raw_create
(struct mail_user *ruser, struct istream *input,
	const char *mailfile, const char *sender, time_t mtime)
{
	struct mail_raw *mailr;
	struct mailbox_header_lookup_ctx *headers_ctx;
	const char *envelope_sender;
	int ret;

	if ( mailfile != NULL && *mailfile != '/' )
		mailfile = t_abspath(mailfile);

	mailr = i_new(struct mail_raw, 1);

	envelope_sender = sender != NULL ? sender : DEFAULT_ENVELOPE_SENDER;
	if ( mailfile == NULL ) {
		ret = raw_mailbox_alloc_stream(ruser, input, mtime,
					       envelope_sender, &mailr->box);
	} else {
		ret = raw_mailbox_alloc_path(ruser, mailfile, (time_t)-1,
					     envelope_sender, &mailr->box);
	}

	if ( ret < 0 ) {
		if ( mailfile == NULL ) {
			i_fatal("Can't open delivery mail as raw: %s",
				mailbox_get_last_error(mailr->box, NULL));
		} else {
			i_fatal("Can't open delivery mail as raw (file=%s): %s",
				mailfile, mailbox_get_last_error(mailr->box, NULL));
		}
	}

	mailr->trans = mailbox_transaction_begin(mailr->box, 0);
	headers_ctx = mailbox_header_lookup_init(mailr->box, wanted_headers);
	mailr->mail = mail_alloc(mailr->trans, 0, headers_ctx);
	mailbox_header_lookup_unref(&headers_ctx);
	mail_set_seq(mailr->mail, 1);

	return mailr;
}
예제 #9
0
static int
virtual_mail_get_header_stream(struct mail *mail,
			       struct mailbox_header_lookup_ctx *headers,
			       struct istream **stream_r)
{
	struct virtual_mail *vmail = (struct virtual_mail *)mail;
	struct mailbox_header_lookup_ctx *backend_headers;
	int ret;

	if (virtual_mail_handle_lost(vmail) < 0)
		return -1;

	backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
						     headers->headers);
	ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
				     stream_r);
	mailbox_header_lookup_unref(&backend_headers);
	if (ret < 0) {
		virtual_box_copy_error(mail->box, vmail->backend_mail->box);
		return -1;
	}
	return 0;
}
예제 #10
0
파일: imapc-mail.c 프로젝트: bjacke/core
static int
imapc_mail_get_headers(struct mail *_mail, const char *field,
		       bool decode_to_utf8, const char *const **value_r)
{
	struct mailbox_header_lookup_ctx *headers;
	const char *header_names[2];
	const unsigned char *data;
	size_t size;
	struct istream *input;
	int ret;

	header_names[0] = field;
	header_names[1] = NULL;
	headers = mailbox_header_lookup_init(_mail->box, header_names);
	ret = mail_get_header_stream(_mail, headers, &input);
	mailbox_header_lookup_unref(&headers);
	if (ret < 0)
		return -1;

	while (i_stream_read_data(input, &data, &size, 0) > 0)
		i_stream_skip(input, size);
	/* the header should cached now. */
	return index_mail_get_headers(_mail, field, decode_to_utf8, value_r);
}