bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainenrawlog_write_timestamp(struct rawlog_iostream *rstream, bool line_ends)
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen unsigned char data[MAX_INT_STRLEN + 6 + 1 + 3];
b367011da1a2ba3e9113dfbc601aaa4b6b04317dTimo Sirainen if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_TIMESTAMP) == 0)
3281669db44d09a087a203201248abbc81b3cc1aTimo Sirainen buffer_create_from_data(&buf, data, sizeof(data));
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0) {
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen str_append_c(&buf, rstream->input ? 'I' : 'O');
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen o_stream_nsend(rstream->rawlog_output, buf.data, buf.used);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainenvoid iostream_rawlog_init(struct rawlog_iostream *rstream,
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0)
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen rstream->buffer = buffer_create_dynamic(default_pool, 1024);
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Siraineniostream_rawlog_write_buffered(struct rawlog_iostream *rstream,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen const unsigned char *p;
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen while (size > 0) {
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen } else if (rstream->buffer->used + size < RAWLOG_MAX_LINE_LEN) {
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen o_stream_nsend(rstream->rawlog_output, data, pos);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Siraineniostream_rawlog_write_unbuffered(struct rawlog_iostream *rstream,
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen rstream->line_continued = data[size-1] != '\n';
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainenvoid iostream_rawlog_write(struct rawlog_iostream *rstream,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen if (size == 0 || rstream->rawlog_output == NULL)
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0)
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen iostream_rawlog_write_buffered(rstream, data, size);
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen iostream_rawlog_write_unbuffered(rstream, data, size);
d1ba8ecbb936ace90179d2292952546708d68f71Timo Sirainen if (o_stream_flush(rstream->rawlog_output) < 0) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenvoid iostream_rawlog_close(struct rawlog_iostream *rstream)
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Siraineniostream_rawlog_create_fd(int fd, const char *path, struct istream **input,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen *input = i_stream_create_rawlog(old_input, path, fd,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen *output = o_stream_create_rawlog(old_output, path, fd,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Siraineniostream_rawlog_try_create_tcp(const char *path,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen struct istream **input, struct ostream **output)
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen /* tcp:host:port */
7c925149e49f7cce41c90d562ff3835b66ddca29Timo Sirainen if (net_str2hostport(path, 0, &host, &port) < 0 || port == 0)
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen ret = net_gethostbyname(host, &ips, &ips_count);
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen i_error("net_gethostbyname(%s) failed: %s", host,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen fd = net_connect_ip_blocking(&ips[0], port, NULL);
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen i_error("connect(%s:%u) failed: %m", net_ip2addr(&ips[0]), port);
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen iostream_rawlog_create_fd(fd, path, input, output);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenint iostream_rawlog_create(const char *dir, struct istream **input,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen if ((ret = iostream_rawlog_try_create_tcp(dir, input, output)) != 0)
b1f37113a5760bee842c5a7678bb5fa6f5bd8b60Timo Sirainen timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen prefix = t_strdup_printf("%s/%s.%s.%u", dir, timestamp, my_pid, counter);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen return iostream_rawlog_create_prefix(prefix, input, output);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainenint iostream_rawlog_create_prefix(const char *prefix, struct istream **input,
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen in_fd = open(in_path, O_CREAT | O_APPEND | O_WRONLY, 0600);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen out_fd = open(out_path, O_CREAT | O_APPEND | O_WRONLY, 0600);
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen *input = i_stream_create_rawlog(old_input, in_path, in_fd,
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen *output = o_stream_create_rawlog(old_output, out_path, out_fd,
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainenint iostream_rawlog_create_path(const char *path, struct istream **input,
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen if ((ret = iostream_rawlog_try_create_tcp(path, input, output)) != 0)
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0600);
f9b6b5e9c4e18682321959883c888035a56b6be9Timo Sirainen iostream_rawlog_create_fd(fd, path, input, output);
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainenvoid iostream_rawlog_create_from_stream(struct ostream *rawlog_output,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen const enum iostream_rawlog_flags rawlog_flags =
fc64b2b538099893e2c2dde103b5c5af1d05d6daTimo Sirainen *input = i_stream_create_rawlog_from_stream(old_input,