#include "safe-mkstemp.h"
#include "istream-private.h"
#include "istream-seekable.h"
+#include "ostream-dot.h"
+#include "istream-dot.h"
#include "ostream.h"
#include "lib-signals.h"
void program_client_disconnected(struct program_client *pclient)
{
if (pclient->program_input != NULL) {
- if (pclient->output_seekable)
+ if (pclient->output_seekable ||
+ pclient->set.use_dotstream)
i_stream_unref(&pclient->program_input);
else
i_stream_destroy(&pclient->program_input);
return ret;
}
+ if (!pclient->output_dot_created &&
+ pclient->set.use_dotstream &&
+ output != NULL) {
+ pclient->dot_output = o_stream_create_dot(output, FALSE);
+ pclient->output_dot_created = TRUE;
+ }
+ if (pclient->output_dot_created &&
+ pclient->dot_output != NULL)
+ output = pclient->dot_output;
+
if (input != NULL && output != NULL) {
res = o_stream_send_istream(output, input);
-
switch (res) {
case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
+ if (pclient->output_dot_created) {
+ if ((ret = o_stream_flush(pclient->dot_output)) <= 0) {
+ if (ret < 0) {
+ i_error("write(%s) failed: %s",
+ o_stream_get_name(pclient->dot_output),
+ o_stream_get_error(pclient->dot_output));
+ program_client_fail(pclient,
+ PROGRAM_CLIENT_ERROR_IO);
+ }
+ }
+ o_stream_unref(&pclient->dot_output);
+ output = pclient->program_output;
+ }
i_stream_unref(&pclient->input);
input = NULL;
break;
program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
return -1;
}
+ } else if (input == NULL &&
+ output != NULL &&
+ pclient->output_dot_created) {
+ if ((ret = o_stream_flush(pclient->dot_output)) <= 0) {
+ if (ret < 0) {
+ i_error("write(%s) failed: %s",
+ o_stream_get_name(output),
+ o_stream_get_error(output));
+ program_client_fail(pclient,
+ PROGRAM_CLIENT_ERROR_IO);
+ }
+ return ret;
+ }
+ o_stream_unref(&pclient->dot_output);
}
if (input == NULL) {
}
if (input != NULL) {
+ if (!pclient->input_dot_created &&
+ pclient->set.use_dotstream) {
+ pclient->dot_input = i_stream_create_dot(input, FALSE);
+ pclient->input_dot_created = TRUE;
+ }
+ if (pclient->input_dot_created &&
+ pclient->dot_input != NULL)
+ input = pclient->dot_input;
+ else if (pclient->set.use_dotstream) {
+ /* just read it empty */
+ while(i_stream_read_more(input, &data,
+ &size) > 0)
+ i_stream_skip(input, size);
+ output = NULL;
+ }
if (output != NULL) {
res = o_stream_send_istream(output, input);
-
switch (res) {
case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
+ if (pclient->set.use_dotstream &&
+ pclient->dot_input != NULL) {
+ i_stream_unref(&pclient->dot_input);
+ input = pclient->program_input;
+ }
break;
case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
o_stream_set_name(pclient->program_output, "program stdin");
}
if (pclient->fd_in >= 0) {
- struct istream *input;
-
- input = i_stream_create_fd(pclient->fd_in, (size_t)-1);
-
- pclient->program_input = input;
+ pclient->program_input =
+ i_stream_create_fd(pclient->fd_in, (size_t)-1);
i_stream_set_name(pclient->program_input, "program stdout");
-
pclient->io = io_add(pclient->fd_in, IO_READ,
program_client_program_input, pclient);
}
if (pclient->input != NULL)
i_stream_unref(&pclient->input);
+ if (pclient->dot_input != NULL)
+ i_stream_unref(&pclient->dot_input);
if (pclient->program_input != NULL)
i_stream_unref(&pclient->program_input);
if (pclient->program_output != NULL)
#include "array.h"
#include "istream.h"
#include "ostream.h"
+#include "istream-dot.h"
+#include "ostream-dot.h"
#include "net.h"
#include "iostream-temp.h"
#include "program-client.h"
#include <unistd.h>
-static const char *pclient_test_io_string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
- "Praesent vehicula ac leo vel placerat. Nullam placerat \n"
- "volutpat leo, sed ultricies felis pulvinar quis. Nam \n"
- "tempus, augue ut tempor cursus, neque felis commodo lacus, \n"
- "sit amet tincidunt arcu justo vel augue. Proin dapibus \n"
- "vulputate maximus. Mauris congue lacus felis, sed varius \n"
- "leo finibus sagittis. Cum sociis natoque penatibus et magnis \n"
- "dis parturient montes, nascetur ridiculus mus. Aliquam \n"
+static const char *pclient_test_io_string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\n"
+ "Praesent vehicula ac leo vel placerat. Nullam placerat \r\n"
+ "volutpat leo, sed ultricies felis pulvinar quis. Nam \r\n"
+ "tempus, augue ut tempor cursus, neque felis commodo lacus, \r\n"
+ "sit amet tincidunt arcu justo vel augue. Proin dapibus \r\n"
+ "vulputate maximus. Mauris congue lacus felis, sed varius \r\n"
+ "leo finibus sagittis. Cum sociis natoque penatibus et magnis \r\n"
+ "dis parturient montes, nascetur ridiculus mus. Aliquam \r\n"
"laoreet arcu a hendrerit consequat. Duis vitae erat tellus.";
static
{
int cmp = -1;
const char *arg;
+ struct istream *is;
switch(client->state) {
case CLIENT_STATE_INIT:
break;
case CLIENT_STATE_BODY:
client->os_body =
- iostream_temp_create_named(".dovecot.test.",
- 0, "test_program_input body");
+ iostream_temp_create_named(".dovecot.test.", 0,
+ "test_program_input body");
+ is = client->in;
+ client->in = i_stream_create_dot(is, FALSE);
+ i_stream_unref(&is);
+
switch(o_stream_send_istream(client->os_body, client->in)) {
case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
break;
case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
- client->body = iostream_temp_finish(&client->os_body, -1);
+ client->body = iostream_temp_finish(&client->os_body,
+ -1);
return 1;
case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
i_panic("Cannot write to ostream-temp");
{
const char *arg;
- timeout_remove(&test_globals.to);
+ struct ostream *os;
- test_assert(array_count(&client->args) > 0);
- arg = *array_idx(&client->args, 0);
- if (strcmp(arg, "test_program_success")==0) {
- /* return hello world */
- o_stream_nsend_str(client->out, t_strdup_printf("%s %s\n+\n",
- *array_idx(&client->args, 1),
- *array_idx(&client->args, 2)));
- } else if (strcmp(arg, "test_program_io")==0) {
- o_stream_send_istream(client->out, client->body);
- o_stream_nsend_str(client->out, "+\n");
- } else if (strcmp(arg, "test_program_failure")==0) {
- o_stream_nsend_str(client->out, "-\n");
+ timeout_remove(&test_globals.to);
+ test_assert(array_is_created(&client->args));
+ if (array_is_created(&client->args)) {
+ test_assert(array_count(&client->args) > 0);
+ if (array_count(&client->args) > 0) {
+ arg = *array_idx(&client->args, 0);
+ if (strcmp(arg, "test_program_success")==0) {
+ /* return hello world */
+ o_stream_nsend_str(client->out, t_strdup_printf(
+ "%s %s\r\n.\n+\n",
+ *array_idx(&client->args, 1),
+ *array_idx(&client->args, 2)));
+ } else if (strcmp(arg, "test_program_io")==0) {
+ os = o_stream_create_dot(client->out, FALSE);
+ o_stream_send_istream(os, client->body);
+ o_stream_flush(os);
+ o_stream_unref(&os);
+ o_stream_nsend_str(client->out, "+\n");
+ } else if (strcmp(arg, "test_program_failure")==0) {
+ o_stream_nsend_str(client->out, ".\n-\n");
+ }
+ } else
+ o_stream_nsend_str(client->out, ".\n-\n");
}
+ test_program_client_destroy(&client);
}
static
void test_program_input(struct test_client *client)
-
{
const char *line = "";
+ int ret = 0;
if (client->state == CLIENT_STATE_BODY) {
if (test_program_input_handle(client, NULL)==0 &&
!client->in->eof)
return;
} else {
- line = i_stream_read_next_line(client->in);
+ while((line = i_stream_read_next_line(client->in)) != NULL) {
+ ret = test_program_input_handle(client, line);
+ if (client->state == CLIENT_STATE_BODY)
+ ret = test_program_input_handle(client, NULL);
+ if (ret != 0) break;
+ }
if ((line == NULL && !client->in->eof) ||
- (line != NULL && test_program_input_handle(client, line) == 0))
+ (line != NULL &&
+ ret == 0))
return;
}
else
i_warning("Client sent invalid line: %s", line);
}
-
- test_program_client_destroy(&client);
}
static
net_addr2ip("127.0.0.1", &ip);
test_globals.listen_fd = net_listen(&ip, &test_globals.port, 1);
-;
+
if (test_globals.listen_fd < 0)
i_fatal("Cannot create TCP listener: %m");
};
struct program_client *pc =
- program_client_net_create("95.175.99.158", 33333, args,
+ program_client_net_create("127.0.0.1", test_globals.port, args,
&pc_set, FALSE);
buffer_t *output = buffer_create_dynamic(default_pool, 16);
test_program_io_loop_run();
test_assert(ret == 1);
- test_assert(strcmp(str_c(output), "hello world\n") == 0);
+ test_assert(strcmp(str_c(output), "hello world") == 0);
program_client_destroy(&pc);