예제 #1
0
bool cmd_idle(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_idle_context *ctx;

	ctx = p_new(cmd->pool, struct cmd_idle_context, 1);
	ctx->cmd = cmd;
	ctx->client = client;
	idle_add_keepalive_timeout(ctx);

	if (client->mailbox != NULL)
		mailbox_notify_changes(client->mailbox, idle_callback, ctx);
	client_send_line(client, "+ idling");

	io_remove(&client->io);
	client->io = io_add(i_stream_get_fd(client->input),
			    IO_READ, idle_client_input, ctx);

	cmd->func = cmd_idle_continue;
	cmd->context = ctx;

	/* check immediately if there are changes. if they came before we
	   added mailbox-notifier, we wouldn't see them otherwise. */
	if (client->mailbox != NULL)
		idle_sync_now(client->mailbox, ctx);
	return idle_client_handle_input(ctx, FALSE);
}
예제 #2
0
static int o_stream_temp_dup_istream(struct temp_ostream *outstream,
				     struct istream *instream)
{
	uoff_t in_size;
	off_t ret;

	if (!instream->readable_fd || i_stream_get_fd(instream) == -1)
		return 0;

	if (i_stream_get_size(instream, TRUE, &in_size) <= 0) {
		if (outstream->dupstream != NULL)
			return o_stream_temp_dup_cancel(outstream);
		return 0;
	}

	if (outstream->dupstream == NULL) {
		outstream->dupstream = instream;
		outstream->dupstream_start_offset = instream->v_offset;
		i_stream_ref(outstream->dupstream);
	} else {
		if (outstream->dupstream != instream ||
		    outstream->dupstream_offset != instream->v_offset ||
		    outstream->dupstream_offset > in_size)
			return o_stream_temp_dup_cancel(outstream);
	}
	ret = in_size - instream->v_offset;
	i_stream_seek(instream, in_size);
	outstream->dupstream_offset = instream->v_offset;
	return ret;
}
예제 #3
0
struct istream *
http_server_request_get_payload_input(struct http_server_request *req,
	bool blocking)
{
	struct http_server_istream *hsristream;
	struct istream *payload = req->req.payload;

	i_assert(req->payload_input == NULL);

	hsristream = i_new(struct http_server_istream, 1);
	hsristream->req = req;
	hsristream->istream.max_buffer_size =
		payload->real_stream->max_buffer_size;
	hsristream->istream.stream_size_passthrough = TRUE;

	hsristream->istream.read = http_server_istream_read;
	hsristream->istream.switch_ioloop = http_server_istream_switch_ioloop;
	hsristream->istream.iostream.destroy = http_server_istream_destroy;

	hsristream->istream.istream.readable_fd = FALSE;
	hsristream->istream.istream.blocking = blocking;
	hsristream->istream.istream.seekable = FALSE;

	req->payload_input = i_stream_create
		(&hsristream->istream, payload, i_stream_get_fd(payload));
	i_stream_unref(&req->req.payload);
	return req->payload_input;
}
예제 #4
0
static bool cmd_putscript_start
(struct client_command_context *cmd, const char *scriptname)
{
	struct cmd_putscript_context *ctx;
	struct client *client = cmd->client;

	ctx = p_new(cmd->pool, struct cmd_putscript_context, 1);
	ctx->cmd = cmd;
	ctx->client = client;
	ctx->storage = client->storage;
	ctx->scriptname = scriptname;

	io_remove(&client->io);
	client->io = io_add(i_stream_get_fd(client->input), IO_READ,
			    client_input_putscript, client);
	/* putscript is special because we're only waiting on client input, not
	   client output, so disable the standard output handler until we're
	   finished */
	o_stream_unset_flush_callback(client->output);

	ctx->save_parser = managesieve_parser_create
		(client->input, client->set->managesieve_max_line_length);

	cmd->func = cmd_putscript_continue_parsing;
	cmd->context = ctx;
	return cmd_putscript_continue_parsing(cmd);

}
예제 #5
0
struct istream *tee_i_stream_create_child(struct tee_istream *tee)
{
	struct tee_child_istream *tstream;
	struct istream *ret, *input = tee->input;

	tstream = i_new(struct tee_child_istream, 1);
	tstream->tee = tee;

	tstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	tstream->istream.iostream.close = i_stream_tee_close;
	tstream->istream.iostream.destroy = i_stream_tee_destroy;
	tstream->istream.iostream.set_max_buffer_size =
		i_stream_tee_set_max_buffer_size;

	tstream->istream.read = i_stream_tee_read;
	tstream->istream.stat = i_stream_tee_stat;
	tstream->istream.sync = i_stream_tee_sync;

	tstream->next = tee->children;
	tee->children = tstream;

	ret = i_stream_create(&tstream->istream, input, i_stream_get_fd(input));
	i_stream_set_name(&tstream->istream.istream, i_stream_get_name(input));
	/* we keep the reference in tee stream, no need for extra references */
	i_stream_unref(&input);
	return ret;
}
struct istream *
i_stream_create_rawlog(struct istream *input, const char *rawlog_path,
		       int rawlog_fd, enum iostream_rawlog_flags flags)
{
	struct rawlog_istream *rstream;

	i_assert(rawlog_path != NULL);
	i_assert(rawlog_fd != -1);

	rstream = i_new(struct rawlog_istream, 1);
	rstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	rstream->istream.stream_size_passthrough = TRUE;

	rstream->riostream.rawlog_path = i_strdup(rawlog_path);
	rstream->riostream.rawlog_fd = rawlog_fd;
	iostream_rawlog_init(&rstream->riostream, flags, TRUE);

	rstream->istream.read = i_stream_rawlog_read;
	rstream->istream.iostream.close = i_stream_rawlog_close;
	rstream->istream.iostream.destroy = i_stream_rawlog_destroy;

	rstream->istream.istream.readable_fd = input->readable_fd;
	rstream->istream.istream.blocking = input->blocking;
	rstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&rstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #7
0
struct istream *i_stream_create_lzma(struct istream *input, bool log_errors)
{
	struct lzma_istream *zstream;

	zstream = i_new(struct lzma_istream, 1);
	zstream->eof_offset = (uoff_t)-1;
	zstream->stream_size = (uoff_t)-1;
	zstream->log_errors = log_errors;

	i_stream_lzma_init(zstream);

	zstream->istream.iostream.close = i_stream_lzma_close;
	zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	zstream->istream.read = i_stream_lzma_read;
	zstream->istream.seek = i_stream_lzma_seek;
	zstream->istream.stat = i_stream_lzma_stat;
	zstream->istream.sync = i_stream_lzma_sync;

	zstream->istream.istream.readable_fd = FALSE;
	zstream->istream.istream.blocking = input->blocking;
	zstream->istream.istream.seekable = input->seekable;

	return i_stream_create(&zstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #8
0
void connection_init_from_streams(struct connection_list *list,
			    struct connection *conn, const char *name,
			    struct istream *input, struct ostream *output)
{
	i_assert(name != NULL);

	conn->list = list;
	conn->name = i_strdup(name);
	conn->fd_in = i_stream_get_fd(input);
	conn->fd_out = o_stream_get_fd(output);

	i_assert(conn->fd_in >= 0);
	i_assert(conn->fd_out >= 0);
	i_assert(conn->io == NULL);
	i_assert(conn->input == NULL);
	i_assert(conn->output == NULL);
	i_assert(conn->to == NULL);

	conn->input = input;
	i_stream_ref(conn->input);
	i_stream_set_name(conn->input, conn->name);

	conn->output = output;
	o_stream_ref(conn->output);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_set_name(conn->output, conn->name);

	conn->io = io_add_istream(conn->input, *list->v.input, conn);
	
	DLLIST_PREPEND(&list->connections, conn);
	list->connections_count++;

	if (list->v.client_connected != NULL)
		list->v.client_connected(conn, TRUE);
}
예제 #9
0
파일: login-proxy.c 프로젝트: bjacke/core
void login_proxy_detach(struct login_proxy *proxy)
{
	struct client *client = proxy->client;
	const unsigned char *data;
	size_t size;

	i_assert(proxy->client_fd == -1);
	i_assert(proxy->server_input != NULL);
	i_assert(proxy->server_output != NULL);

	if (proxy->to != NULL)
		timeout_remove(&proxy->to);

	proxy->client_fd = i_stream_get_fd(client->input);
	proxy->client_input = client->input;
	proxy->client_output = client->output;

	i_stream_set_persistent_buffers(client->input, FALSE);
	o_stream_set_max_buffer_size(client->output, (size_t)-1);
	o_stream_set_flush_callback(client->output, proxy_client_output, proxy);
	client->input = NULL;
	client->output = NULL;

	/* send all pending client input to proxy */
	data = i_stream_get_data(proxy->client_input, &size);
	if (size != 0)
		o_stream_nsend(proxy->server_output, data, size);

	/* from now on, just do dummy proxying */
	io_remove(&proxy->server_io);
	proxy->server_io =
		io_add(proxy->server_fd, IO_READ, server_input, proxy);
	proxy->client_io =
		io_add_istream(proxy->client_input, proxy_client_input, proxy);
	o_stream_set_flush_callback(proxy->server_output, server_output, proxy);
	i_stream_destroy(&proxy->server_input);

	if (proxy->notify_refresh_secs != 0) {
		proxy->to_notify =
			timeout_add(proxy->notify_refresh_secs * 1000,
				    login_proxy_notify, proxy);
	}

	proxy->callback = NULL;

	if (login_proxy_ipc_server == NULL) {
		login_proxy_ipc_server =
			ipc_server_init(LOGIN_PROXY_IPC_PATH,
					LOGIN_PROXY_IPC_NAME,
					login_proxy_ipc_cmd);
	}

	DLLIST_REMOVE(&login_proxies_pending, proxy);
	DLLIST_PREPEND(&login_proxies, proxy);

	client->fd = -1;
	client->login_proxy = NULL;
}
예제 #10
0
struct istream *iostream_temp_finish(struct ostream **output,
				     size_t max_buffer_size)
{
	struct temp_ostream *tstream =
		(struct temp_ostream *)(*output)->real_stream;
	struct istream *input, *input2;
	uoff_t abs_offset, size;
	const char *for_path;
	int fd;

	if (tstream->name[0] == '\0')
		for_path = "";
	else
		for_path = t_strdup_printf(" for %s", tstream->name);

	if (tstream->dupstream != NULL && !tstream->dupstream->closed) {
		abs_offset = i_stream_get_absolute_offset(tstream->dupstream) -
			tstream->dupstream->v_offset +
			tstream->dupstream_start_offset;
		size = tstream->dupstream_offset -
			tstream->dupstream_start_offset;
		fd = dup(i_stream_get_fd(tstream->dupstream));
		if (fd == -1)
			input = i_stream_create_error_str(errno, "dup() failed: %m");
		else {
			input2 = i_stream_create_fd_autoclose(&fd, max_buffer_size);
			i_stream_seek(input2, abs_offset);
			input = i_stream_create_limit(input2, size);
			i_stream_unref(&input2);
		}
		i_stream_set_name(input, t_strdup_printf(
			"(Temp file in %s%s, from %s)", tstream->temp_path_prefix,
			for_path, i_stream_get_name(tstream->dupstream)));
		i_stream_unref(&tstream->dupstream);
	} else if (tstream->dupstream != NULL) {
		/* return the original failed stream. */
		input = tstream->dupstream;
	} else if (tstream->fd != -1) {
		int fd = tstream->fd;
		input = i_stream_create_fd_autoclose(&tstream->fd, max_buffer_size);
		i_stream_set_name(input, t_strdup_printf(
			"(Temp file fd %d in %s%s, %"PRIuUOFF_T" bytes)",
			fd, tstream->temp_path_prefix, for_path, tstream->fd_size));
	} else {
		input = i_stream_create_from_data(tstream->buf->data,
						  tstream->buf->used);
		i_stream_set_name(input, t_strdup_printf(
			"(Temp buffer in %s%s, %"PRIuSIZE_T" bytes)",
			tstream->temp_path_prefix, for_path, tstream->buf->used));
		i_stream_add_destroy_callback(input, iostream_temp_buf_destroyed,
					      tstream->buf);
		tstream->buf = NULL;
	}
	o_stream_destroy(output);
	return input;
}
예제 #11
0
static int maildir_mail_stat(struct mail *mail, struct stat *st_r)
{
	struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box;
	struct index_mail *imail = (struct index_mail *)mail;
	const char *path;
	int fd, ret;

	if (mail->lookup_abort == MAIL_LOOKUP_ABORT_NOT_IN_CACHE) {
		mail_set_aborted(mail);
		return -1;
	}

	if (imail->data.access_part != 0 &&
	    imail->data.stream == NULL) {
		/* we're going to open the mail anyway */
		struct istream *input;

		(void)mail_get_stream(mail, NULL, NULL, &input);
	}

	if (imail->data.stream != NULL &&
	    (fd = i_stream_get_fd(imail->data.stream)) != -1) {
		mail->transaction->stats.fstat_lookup_count++;
		if (fstat(fd, st_r) < 0) {
			mail_storage_set_critical(mail->box->storage,
				"fstat(%s) failed: %m",
				i_stream_get_name(imail->data.stream));
			return -1;
		}
	} else if (!mail->saving) {
		mail->transaction->stats.stat_lookup_count++;
		ret = maildir_file_do(mbox, mail->uid, do_stat, st_r);
		if (ret <= 0) {
			if (ret == 0)
				mail_set_expunged(mail);
			return -1;
		}
	} else {
		mail->transaction->stats.stat_lookup_count++;
		path = maildir_save_file_get_path(mail->transaction, mail->seq);
		if (stat(path, st_r) < 0) {
			mail_storage_set_critical(mail->box->storage,
						  "stat(%s) failed: %m", path);
			return -1;
		}
	}
	return 0;
}
예제 #12
0
struct istream *i_stream_create_qp_decoder(struct istream *input)
{
	struct qp_decoder_istream *bstream;

	bstream = i_new(struct qp_decoder_istream, 1);
	bstream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	bstream->istream.read = i_stream_qp_decoder_read;
	bstream->istream.seek = i_stream_qp_decoder_seek;

	bstream->istream.istream.readable_fd = FALSE;
	bstream->istream.istream.blocking = input->blocking;
	bstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&bstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #13
0
bool cmd_append(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
        struct cmd_append_context *ctx;
	const char *mailbox;

	if (client->syncing) {
		/* if transaction is created while its view is synced,
		   appends aren't allowed for it. */
		cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
		return FALSE;
	}

	/* <mailbox> */
	if (!client_read_string_args(cmd, 1, &mailbox))
		return FALSE;

	/* we keep the input locked all the time */
	client->input_lock = cmd;

	ctx = p_new(cmd->pool, struct cmd_append_context, 1);
	ctx->cmd = cmd;
	ctx->client = client;
	ctx->started = ioloop_time;
	if (client_open_save_dest_box(cmd, mailbox, &ctx->box) < 0)
		ctx->failed = TRUE;
	else {
		ctx->t = mailbox_transaction_begin(ctx->box,
					MAILBOX_TRANSACTION_FLAG_EXTERNAL |
					MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
	}

	io_remove(&client->io);
	client->io = io_add(i_stream_get_fd(client->input), IO_READ,
			    client_input_append, cmd);
	/* append is special because we're only waiting on client input, not
	   client output, so disable the standard output handler until we're
	   finished */
	o_stream_unset_flush_callback(client->output);

	ctx->save_parser = imap_parser_create(client->input, client->output,
					      client->set->imap_max_line_length);

	cmd->func = cmd_append_parse_new_msg;
	cmd->context = ctx;
	return cmd_append_parse_new_msg(cmd);
}
struct istream *i_stream_create_nonuls(struct istream *input, char replace_chr)
{
	struct nonuls_istream *nstream;

	nstream = i_new(struct nonuls_istream, 1);
	nstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	nstream->istream.stream_size_passthrough = TRUE;

	nstream->istream.read = i_stream_nonuls_read;

	nstream->istream.istream.readable_fd = FALSE;
	nstream->istream.istream.blocking = input->blocking;
	nstream->istream.istream.seekable = FALSE;
	nstream->replace_chr = replace_chr;
	return i_stream_create(&nstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #15
0
struct istream *
http_transfer_chunked_istream_create(struct istream *input)
{
	struct http_transfer_chunked_istream *tcstream;

	tcstream = i_new(struct http_transfer_chunked_istream, 1);

	tcstream->istream.max_buffer_size =
		input->real_stream->max_buffer_size;

	tcstream->istream.iostream.destroy = http_transfer_chunked_istream_destroy;
	tcstream->istream.read = http_transfer_chunked_istream_read;

	tcstream->istream.istream.readable_fd = FALSE;
	tcstream->istream.istream.blocking = input->blocking;
	tcstream->istream.istream.seekable = FALSE;
	return i_stream_create(&tcstream->istream, input, i_stream_get_fd(input));
}
예제 #16
0
struct istream *i_stream_create_dot(struct istream *input, bool send_last_lf)
{
	struct dot_istream *dstream;

	dstream = i_new(struct dot_istream, 1);
	dstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	dstream->istream.read = i_stream_dot_read;

	dstream->istream.istream.readable_fd = FALSE;
	dstream->istream.istream.blocking = input->blocking;
	dstream->istream.istream.seekable = FALSE;
	dstream->send_last_lf = send_last_lf;
	dstream->state = 2;
	dstream->state_no_cr = TRUE;
	dstream->state_no_lf = TRUE;
	return i_stream_create(&dstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #17
0
struct istream *openssl_i_stream_create_ssl(struct ssl_iostream *ssl_io)
{
	struct ssl_istream *sstream;

	ssl_io->refcount++;

	sstream = i_new(struct ssl_istream, 1);
	sstream->ssl_io = ssl_io;
	sstream->istream.iostream.close = i_stream_ssl_close;
	sstream->istream.iostream.destroy = i_stream_ssl_destroy;
	sstream->istream.max_buffer_size =
		ssl_io->plain_input->real_stream->max_buffer_size;
	sstream->istream.read = i_stream_ssl_read;

	sstream->istream.istream.readable_fd = FALSE;
	return i_stream_create(&sstream->istream, NULL,
			       i_stream_get_fd(ssl_io->plain_input));
}
예제 #18
0
struct istream *i_stream_create_mail_stats_counter(struct mail_private *mail,
						   struct istream *input)
{
	struct mail_stats_istream *mstream;

	mstream = i_new(struct mail_stats_istream, 1);
	mstream->mail = mail;
	mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	mstream->istream.parent = input;
	mstream->istream.read = i_stream_mail_stats_read_mail_stats;
	mstream->istream.seek = i_stream_mail_stats_seek;
	mstream->istream.stat = i_stream_mail_stats_stat;

	mstream->istream.istream.blocking = input->blocking;
	mstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&mstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #19
0
struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size)
{
	struct limit_istream *lstream;

	lstream = i_new(struct limit_istream, 1);
	lstream->v_size = v_size;
	lstream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	lstream->istream.iostream.destroy = i_stream_limit_destroy;
	lstream->istream.read = i_stream_limit_read;
	lstream->istream.stat = i_stream_limit_stat;
	lstream->istream.get_size = i_stream_limit_get_size;

	lstream->istream.istream.readable_fd = input->readable_fd;
	lstream->istream.istream.blocking = input->blocking;
	lstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&lstream->istream, input,
			       i_stream_get_fd(input));
}
static struct istream *quoted_string_istream_create
(struct managesieve_parser *parser)
{
	struct quoted_string_istream *qsstream;

	qsstream = i_new(struct quoted_string_istream, 1);
	qsstream->parser = parser;

	qsstream->istream.max_buffer_size =
		parser->input->real_stream->max_buffer_size;

	qsstream->istream.read = quoted_string_istream_read;
	qsstream->istream.stat = quoted_string_istream_stat;

	qsstream->istream.istream.readable_fd = FALSE;
	qsstream->istream.istream.blocking = parser->input->blocking;
	qsstream->istream.istream.seekable = FALSE;
	return i_stream_create(&qsstream->istream, parser->input,
			       i_stream_get_fd(parser->input));
}
예제 #21
0
struct istream *i_stream_create_mail(struct mail *mail, struct istream *input,
				     bool input_has_body)
{
	struct mail_istream *mstream;

	mstream = i_new(struct mail_istream, 1);
	mstream->mail = mail;
	mstream->input_has_body = input_has_body;
	mstream->expected_size = (uoff_t)-1;
	(void)i_stream_mail_try_get_cached_size(mstream);
	mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	mstream->istream.stream_size_passthrough = TRUE;

	mstream->istream.read = i_stream_mail_read;

	mstream->istream.istream.blocking = input->blocking;
	mstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&mstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #22
0
struct istream *
i_stream_create_hash(struct istream *input, const struct hash_method *method,
		     void *hash_context)
{
	struct hash_istream *hstream;

	hstream = i_new(struct hash_istream, 1);
	hstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	hstream->istream.stream_size_passthrough = TRUE;

	hstream->istream.read = i_stream_hash_read;
	hstream->istream.seek = i_stream_hash_seek;

	hstream->istream.istream.blocking = input->blocking;
	hstream->istream.istream.seekable = input->seekable;

	hstream->method = method;
	hstream->hash_context = hash_context;
	return i_stream_create(&hstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #23
0
static
struct decrypt_istream *i_stream_create_decrypt_common(struct istream *input)
{
	struct decrypt_istream *dstream;

	dstream = i_new(struct decrypt_istream, 1);
	dstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	dstream->istream.read = i_stream_decrypt_read;
	dstream->istream.iostream.close = i_stream_decrypt_close;
	dstream->istream.iostream.destroy = i_stream_decrypt_destroy;

	dstream->istream.istream.readable_fd = FALSE;
	dstream->istream.istream.blocking = input->blocking;
	dstream->istream.istream.seekable = FALSE;

	dstream->buf = buffer_create_dynamic(default_pool, 512);

	(void)i_stream_create(&dstream->istream, input,
			      i_stream_get_fd(input));
	return dstream;
}
예제 #24
0
struct istream *
i_stream_create_metawrap(struct istream *input,
			 metawrap_callback_t *callback, void *context)
{
	struct metawrap_istream *mstream;

	mstream = i_new(struct metawrap_istream, 1);
	mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	mstream->istream.read = i_stream_metawrap_read;
	mstream->istream.seek = i_stream_metawrap_seek;
	mstream->istream.stat = input->seekable ? i_stream_metawrap_stat : NULL;

	mstream->istream.istream.readable_fd = input->readable_fd;
	mstream->istream.istream.blocking = input->blocking;
	mstream->istream.istream.seekable = input->seekable;
	mstream->in_metadata = TRUE;
	mstream->callback = callback;
	mstream->context = context;
	return i_stream_create(&mstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #25
0
struct istream *
i_stream_create_base64_encoder(struct istream *input,
			       unsigned int chars_per_line, bool crlf)
{
	struct base64_encoder_istream *bstream;

	i_assert(chars_per_line % 4 == 0);

	bstream = i_new(struct base64_encoder_istream, 1);
	bstream->chars_per_line = chars_per_line;
	bstream->crlf = crlf;
	bstream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	bstream->istream.read = i_stream_base64_encoder_read;
	bstream->istream.seek = i_stream_base64_encoder_seek;

	bstream->istream.istream.readable_fd = FALSE;
	bstream->istream.istream.blocking = input->blocking;
	bstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&bstream->istream, input,
			       i_stream_get_fd(input));
}
struct istream *
i_stream_create_failure_at(struct istream *input, uoff_t failure_offset,
			   const char *error_string)
{
	struct failure_at_istream *fstream;

	fstream = i_new(struct failure_at_istream, 1);
	fstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	fstream->istream.stream_size_passthrough = TRUE;

	fstream->istream.read = i_stream_failure_at_read;
	fstream->istream.iostream.destroy = i_stream_failure_at_destroy;

	fstream->istream.istream.readable_fd = input->readable_fd;
	fstream->istream.istream.blocking = input->blocking;
	fstream->istream.istream.seekable = input->seekable;

	fstream->error_string = i_strdup(error_string);
	fstream->failure_offset = failure_offset;
	return i_stream_create(&fstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #27
0
struct istream *i_stream_create_lz4(struct istream *input, bool log_errors)
{
	struct lz4_istream *zstream;

	zstream = i_new(struct lz4_istream, 1);
	zstream->stream_size = (uoff_t)-1;
	zstream->log_errors = log_errors;

	zstream->istream.iostream.close = i_stream_lz4_close;
	zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	zstream->istream.read = i_stream_lz4_read;
	zstream->istream.seek = i_stream_lz4_seek;
	zstream->istream.stat = i_stream_lz4_stat;
	zstream->istream.sync = i_stream_lz4_sync;

	zstream->istream.istream.readable_fd = FALSE;
	zstream->istream.istream.blocking = input->blocking;
	zstream->istream.istream.seekable = input->seekable;
	zstream->chunk_buf = buffer_create_dynamic(default_pool, 1024);

	return i_stream_create(&zstream->istream, input,
			       i_stream_get_fd(input));
}
예제 #28
0
struct istream *
i_stream_create_attachment_extractor(struct istream *input,
				     struct istream_attachment_settings *set,
				     void *context)
{
	struct attachment_istream *astream;

	i_assert(set->min_size > 0);
	i_assert(set->hash_format != NULL);
	i_assert(set->open_attachment_ostream != NULL);
	i_assert(set->close_attachment_ostream != NULL);

	astream = i_new(struct attachment_istream, 1);
	astream->part.temp_fd = -1;
	astream->set = *set;
	astream->context = context;
	astream->retry_read = TRUE;

	/* make sure the caller doesn't try to double-free this */
	set->hash_format = NULL;

	astream->istream.max_buffer_size = input->real_stream->max_buffer_size;

	astream->istream.read = i_stream_attachment_extractor_read;
	astream->istream.iostream.close = i_stream_attachment_extractor_close;

	astream->istream.istream.readable_fd = FALSE;
	astream->istream.istream.blocking = input->blocking;
	astream->istream.istream.seekable = FALSE;

	astream->pool = pool_alloconly_create("istream attachment", 1024);
	astream->parser = message_parser_init(astream->pool, input, 0,
				MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
				MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
	return i_stream_create(&astream->istream, input,
			       i_stream_get_fd(input));
}
예제 #29
0
static bool
o_stream_temp_dup_istream(struct temp_ostream *outstream,
			  struct istream *instream,
			  enum ostream_send_istream_result *res_r)
{
	uoff_t in_size;

	if (!instream->readable_fd || i_stream_get_fd(instream) == -1)
		return FALSE;

	if (i_stream_get_size(instream, TRUE, &in_size) <= 0) {
		if (outstream->dupstream != NULL)
			return o_stream_temp_dup_cancel(outstream, res_r);
		return FALSE;
	}
	i_assert(instream->v_offset <= in_size);

	if (outstream->dupstream == NULL) {
		outstream->dupstream = instream;
		outstream->dupstream_start_offset = instream->v_offset;
		i_stream_ref(outstream->dupstream);
	} else {
		if (outstream->dupstream != instream ||
		    outstream->dupstream_offset != instream->v_offset ||
		    outstream->dupstream_offset > in_size)
			return o_stream_temp_dup_cancel(outstream, res_r);
	}
	i_stream_seek(instream, in_size);
	/* we should be at EOF now. o_stream_send_istream() asserts if
	   eof isn't set. */
	instream->eof = TRUE;
	outstream->dupstream_offset = instream->v_offset;
	outstream->ostream.ostream.offset =
		outstream->dupstream_offset - outstream->dupstream_start_offset;
	*res_r = OSTREAM_SEND_ISTREAM_RESULT_FINISHED;
	return TRUE;
}
예제 #30
0
struct istream *
i_stream_create_rawlog_from_stream(struct istream *input,
				   struct ostream *rawlog_output,
				   enum iostream_rawlog_flags flags)
{
	struct rawlog_istream *rstream;

	rstream = i_new(struct rawlog_istream, 1);
	rstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	rstream->istream.stream_size_passthrough = TRUE;

	rstream->riostream.rawlog_output = rawlog_output;
	iostream_rawlog_init(&rstream->riostream, flags, TRUE);

	rstream->istream.read = i_stream_rawlog_read;
	rstream->istream.iostream.close = i_stream_rawlog_close;
	rstream->istream.iostream.destroy = i_stream_rawlog_destroy;

	rstream->istream.istream.readable_fd = input->readable_fd;
	rstream->istream.istream.blocking = input->blocking;
	rstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&rstream->istream, input,
			       i_stream_get_fd(input));
}