bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi */
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi#ifndef IOSTREAM_PROXY_H
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi#define IOSTREAM_PROXY_H 1
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi/**
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomiiostream-proxy
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi=============
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki TuomiThis construct will proxy data between two pairs of
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomiistream and ostream. Data is proxied from left to right
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomiand right to left using iostream-pump.
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki TuomiThe proxy requires you to provide completion callback. The
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomicompletion callback is called with success parameter to
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomiindicate whether it ended with error.
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki TuomiThe istreams and ostreams are reffed on creation and unreffed
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomion unref.
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi**/
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct istream;
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct ostream;
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct iostream_proxy;
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomienum iostream_proxy_side {
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen /* Input is coming from left side's istream and is proxied to
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen right side's ostream. */
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi IOSTREAM_PROXY_SIDE_LEFT,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen /* Input is coming from right side's istream and is proxied to
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen left side's ostream. */
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi IOSTREAM_PROXY_SIDE_RIGHT
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi};
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainenenum iostream_proxy_status {
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen /* proxy succeeded - EOF received from istream and all output was
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen written successfully to ostream. */
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen IOSTREAM_PROXY_STATUS_INPUT_EOF,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen /* proxy failed - istream returned an error */
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen IOSTREAM_PROXY_STATUS_INPUT_ERROR,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen /* proxy failed - other side's ostream returned an error */
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen IOSTREAM_PROXY_STATUS_OTHER_SIDE_OUTPUT_ERROR,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen};
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen/* The callback maybe be called once or twice. Usually the first call should
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen destroy the proxy, but it's possible for it to just wait for the other
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen direction of the proxy to finish as well and call the callback.
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen Note that the sides mean which side is the reader side. If the failure is in
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen ostream, it's the other side's ostream that failed. So for example if
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen side=left, the write failed to the right side's ostream.
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen The callback is called when the proxy succeeds or fails due to
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen iostreams. (It's not called if proxy is destroyed.) */
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomitypedef void iostream_proxy_callback_t(enum iostream_proxy_side side,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen enum iostream_proxy_status status,
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi void *context);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct iostream_proxy *
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomiiostream_proxy_create(struct istream *left_input, struct ostream *left_output,
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi struct istream *right_input, struct ostream *right_output);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct istream *iostream_proxy_get_istream(struct iostream_proxy *proxy, enum iostream_proxy_side);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomistruct ostream *iostream_proxy_get_ostream(struct iostream_proxy *proxy, enum iostream_proxy_side);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_start(struct iostream_proxy *proxy);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_stop(struct iostream_proxy *proxy);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
6ce52edd3de46bdf565ee71f6112a9e7a6090031Timo Sirainen/* See iostream_pump_is_waiting_output() */
6ce52edd3de46bdf565ee71f6112a9e7a6090031Timo Sirainenbool iostream_proxy_is_waiting_output(struct iostream_proxy *proxy,
6ce52edd3de46bdf565ee71f6112a9e7a6090031Timo Sirainen enum iostream_proxy_side side);
6ce52edd3de46bdf565ee71f6112a9e7a6090031Timo Sirainen
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_set_completion_callback(struct iostream_proxy *proxy,
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi iostream_proxy_callback_t *callback, void *context);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi#define iostream_proxy_set_completion_callback(proxy, callback, context) \
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi iostream_proxy_set_completion_callback(proxy, (iostream_proxy_callback_t *)callback, context + \
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)(enum iostream_proxy_side side, enum iostream_proxy_status, typeof(context))))
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_ref(struct iostream_proxy *proxy);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_unref(struct iostream_proxy **proxy_r);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomivoid iostream_proxy_switch_ioloop(struct iostream_proxy *proxy);
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi
26e7bc65f13482709c0f6216650582e7705eeeffAki Tuomi#endif