struct istream *
istream_attachment_connector_finish(struct istream_attachment_connector **_conn)
{
	struct istream_attachment_connector *conn = *_conn;
	struct istream **inputs, *input;
	uoff_t trailer_size;

	*_conn = NULL;

	if (conn->base_input_offset != conn->msg_size) {
		i_assert(conn->base_input_offset < conn->msg_size);

		trailer_size = conn->msg_size - conn->encoded_offset;
		input = i_stream_create_range(conn->base_input,
					      conn->base_input_offset,
					      trailer_size);
		array_append(&conn->streams, &input, 1);
	}
	array_append_zero(&conn->streams);

	inputs = array_idx_modifiable(&conn->streams, 0);
	input = i_stream_create_concat(inputs);

	i_stream_unref(&conn->base_input);
	pool_unref(&conn->pool);
	return input;
}
Esempio n. 2
0
static struct istream *
mbox_save_get_input_stream(struct mbox_save_context *ctx, struct istream *input)
{
	struct istream *filter, *ret, *cache_input, *streams[3];

	/* filter out unwanted headers and keep track of headers' MD5 sum */
	filter = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE |
					       HEADER_FILTER_NO_CR |
					       HEADER_FILTER_ADD_MISSING_EOH |
					       HEADER_FILTER_END_BODY_WITH_LF,
					       mbox_save_drop_headers,
					       mbox_save_drop_headers_count,
					       save_header_callback, ctx);

	if ((ctx->mbox->storage->storage.flags &
	     MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) {
		/* we're using MD5 sums to generate POP3 UIDLs.
		   clients don't like it much if there are duplicates,
		   so make sure that there can't be any by appending
		   our own X-Delivery-ID header. */
		const char *hdr;

		T_BEGIN {
			mbox_save_x_delivery_id(ctx);
		} T_END;
		hdr = ctx->x_delivery_id_header;

		streams[0] = i_stream_create_from_data(hdr, strlen(hdr));
		streams[1] = filter;
		streams[2] = NULL;
		ret = i_stream_create_concat(streams);
		i_stream_unref(&filter);
		filter = ret;
	}

	/* convert linefeeds to wanted format */
	ret = ctx->mbox->storage->storage.set->mail_save_crlf ?
		i_stream_create_crlf(filter) : i_stream_create_lf(filter);
	i_stream_unref(&filter);

	if (ctx->ctx.dest_mail != NULL) {
		/* caching creates a tee stream */
		cache_input =
			index_mail_cache_parse_init(ctx->ctx.dest_mail, ret);
		i_stream_unref(&ret);
		ret = cache_input;
	}
	return ret;
}
Esempio n. 3
0
static int
sieve_attribute_retrieve_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage, struct sieve_script *script,
			   bool add_type_prefix,
			   struct mail_attribute_value *value_r, const char **errorstr_r)
{
	static char type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT;
	struct istream *input, *inputs[3];
	const struct stat *st;
	enum sieve_error error;

	if (script == NULL)
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
	else if (sieve_script_get_stream(script, &input, &error) < 0)
		sieve_script_unref(&script);
	
	if (script == NULL) {
		if (error == SIEVE_ERROR_NOT_FOUND) {
			/* already deleted, but return the last_change */
			(void)sieve_storage_get_last_change(svstorage,
							    &value_r->last_change);
			return 0;
		}
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
		return -1;
	}
	if (i_stream_stat(input, FALSE, &st) < 0) {
		mail_storage_set_critical(storage,
			"stat(%s) failed: %m", i_stream_get_name(input));
	} else {
		value_r->last_change = st->st_mtime;
	}
	if (!add_type_prefix) {
		i_stream_ref(input);
		value_r->value_stream = input;
	} else {
		inputs[0] = i_stream_create_from_data(&type, 1);
		inputs[1] = input;
		inputs[2] = NULL;
		value_r->value_stream = i_stream_create_concat(inputs);
		i_stream_unref(&inputs[0]);
	}
	sieve_script_unref(&script);
	return 1;
}