/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <stddef.h>
#include <unistd.h>

#if HAVE_SELINUX
#include <selinux/selinux.h>
#endif

#include "sd-daemon.h"
#include "sd-event.h"

#include "alloc-util.h"
#include "dirent-util.h"
#include "env-file.h"
#include "errno-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
#include "journald-console.h"
#include "journald-context.h"
#include "journald-kmsg.h"
#include "journald-server.h"
#include "journald-stream.h"
#include "journald-syslog.h"
#include "journald-wall.h"
#include "mkdir.h"
#include "parse-util.h"
#include "process-util.h"
#include "selinux-util.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "syslog-util.h"
#include "tmpfile-util.h"
#include "unit-name.h"

#define STDOUT_STREAMS_MAX 4096

/* During the "setup" protocol phase of the stream logic let's define a different maximum line length than
 * during the actual operational phase. We want to allow users to specify very short line lengths after all,
 * but the unit name we embed in the setup protocol might be longer than that. Hence, during the setup phase
 * let's enforce a line length matching the maximum unit name length (255) */
#define STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX (UNIT_NAME_MAX-1U)

typedef enum StdoutStreamState {
        STDOUT_STREAM_IDENTIFIER,
        STDOUT_STREAM_UNIT_ID,
        STDOUT_STREAM_PRIORITY,
        STDOUT_STREAM_LEVEL_PREFIX,
        STDOUT_STREAM_FORWARD_TO_SYSLOG,
        STDOUT_STREAM_FORWARD_TO_KMSG,
        STDOUT_STREAM_FORWARD_TO_CONSOLE,
        STDOUT_STREAM_RUNNING,
} StdoutStreamState;

/* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length
 * was reached, or the end of the stream was reached */

typedef enum LineBreak {
        LINE_BREAK_NEWLINE,
        LINE_BREAK_NUL,
        LINE_BREAK_LINE_MAX,
        LINE_BREAK_EOF,
        LINE_BREAK_PID_CHANGE,
        _LINE_BREAK_MAX,
        _LINE_BREAK_INVALID = -EINVAL,
} LineBreak;

struct StdoutStream {
        Server *server;
        StdoutStreamState state;

        int fd;

        struct ucred ucred;
        char *label;
        char *identifier;
        char *unit_id;
        int priority;
        bool level_prefix:1;
        bool forward_to_syslog:1;
        bool forward_to_kmsg:1;
        bool forward_to_console:1;

        bool fdstore:1;
        bool in_notify_queue:1;

        char *buffer;
        size_t length;

        sd_event_source *event_source;

        char *state_file;

        ClientContext *context;

        LIST_FIELDS(StdoutStream, stdout_stream);
        LIST_FIELDS(StdoutStream, stdout_stream_notify_queue);

        char id_field[STRLEN("_STREAM_ID=") + SD_ID128_STRING_MAX];
};

StdoutStream* stdout_stream_free(StdoutStream *s) {
        if (!s)
                return NULL;

        if (s->server) {
                if (s->context)
                        client_context_release(s->server, s->context);

                assert(s->server->n_stdout_streams > 0);
                s->server->n_stdout_streams--;
                LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);

                if (s->in_notify_queue)
                        LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);

                (void) server_start_or_stop_idle_timer(s->server); /* Maybe we are idle now? */
        }

        sd_event_source_disable_unref(s->event_source);
        safe_close(s->fd);
        free(s->label);
        free(s->identifier);
        free(s->unit_id);
        free(s->state_file);
        free(s->buffer);

        return mfree(s);
}

DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);

void stdout_stream_destroy(StdoutStream *s) {
        if (!s)
                return;

        if (s->state_file)
                (void) unlink(s->state_file);

        stdout_stream_free(s);
}

static int stdout_stream_save(StdoutStream *s) {
        _cleanup_(unlink_and_freep) char *temp_path = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(s);

        if (s->state != STDOUT_STREAM_RUNNING)
                return 0;

        if (!s->state_file) {
                struct stat st;

                r = fstat(s->fd, &st);
                if (r < 0)
                        return log_warning_errno(errno, "Failed to stat connected stream: %m");

                /* We use device and inode numbers as identifier for the stream */
                r = asprintf(&s->state_file, "%s/streams/%lu:%lu", s->server->runtime_directory, (unsigned long) st.st_dev, (unsigned long) st.st_ino);
                if (r < 0)
                        return log_oom();
        }

        (void) mkdir_parents(s->state_file, 0755);

        r = fopen_temporary(s->state_file, &f, &temp_path);
        if (r < 0)
                goto fail;

        fprintf(f,
                "# This is private data. Do not parse\n"
                "PRIORITY=%i\n"
                "LEVEL_PREFIX=%i\n"
                "FORWARD_TO_SYSLOG=%i\n"
                "FORWARD_TO_KMSG=%i\n"
                "FORWARD_TO_CONSOLE=%i\n"
                "STREAM_ID=%s\n",
                s->priority,
                s->level_prefix,
                s->forward_to_syslog,
                s->forward_to_kmsg,
                s->forward_to_console,
                s->id_field + STRLEN("_STREAM_ID="));

        if (!isempty(s->identifier)) {
                _cleanup_free_ char *escaped = NULL;

                escaped = cescape(s->identifier);
                if (!escaped) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "IDENTIFIER=%s\n", escaped);
        }

        if (!isempty(s->unit_id)) {
                _cleanup_free_ char *escaped = NULL;

                escaped = cescape(s->unit_id);
                if (!escaped) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "UNIT=%s\n", escaped);
        }

        r = fflush_and_check(f);
        if (r < 0)
                goto fail;

        if (rename(temp_path, s->state_file) < 0) {
                r = -errno;
                goto fail;
        }

        temp_path = mfree(temp_path);

        if (!s->fdstore && !s->in_notify_queue) {
                LIST_PREPEND(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
                s->in_notify_queue = true;

                if (s->server->notify_event_source) {
                        r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON);
                        if (r < 0)
                                log_warning_errno(r, "Failed to enable notify event source: %m");
                }
        }

        return 0;

fail:
        (void) unlink(s->state_file);
        return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
}

static int stdout_stream_log(
                StdoutStream *s,
                const char *p,
                LineBreak line_break) {

        struct iovec *iovec;
        int priority;
        char syslog_priority[] = "PRIORITY=\0";
        char syslog_facility[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int) + 1];
        _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
        size_t n = 0, m;
        int r;

        assert(s);
        assert(p);

        assert(line_break >= 0);
        assert(line_break < _LINE_BREAK_MAX);

        if (s->context)
                (void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
        else if (pid_is_valid(s->ucred.pid)) {
                r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
                if (r < 0)
                        log_warning_errno(r, "Failed to acquire client context, ignoring: %m");
        }

        priority = s->priority;

        if (s->level_prefix)
                syslog_parse_priority(&p, &priority, false);

        if (!client_context_test_priority(s->context, priority))
                return 0;

        if (isempty(p))
                return 0;

        if (s->forward_to_syslog || s->server->forward_to_syslog)
                server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);

        if (s->forward_to_kmsg || s->server->forward_to_kmsg)
                server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);

        if (s->forward_to_console || s->server->forward_to_console)
                server_forward_console(s->server, priority, s->identifier, p, &s->ucred);

        if (s->server->forward_to_wall)
                server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);

        m = N_IOVEC_META_FIELDS + 7 + client_context_extra_fields_n_iovec(s->context);
        iovec = newa(struct iovec, m);

        iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout");
        iovec[n++] = IOVEC_MAKE_STRING(s->id_field);

        syslog_priority[STRLEN("PRIORITY=")] = '0' + LOG_PRI(priority);
        iovec[n++] = IOVEC_MAKE_STRING(syslog_priority);

        if (priority & LOG_FACMASK) {
                xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
                iovec[n++] = IOVEC_MAKE_STRING(syslog_facility);
        }

        if (s->identifier) {
                syslog_identifier = strjoin("SYSLOG_IDENTIFIER=", s->identifier);
                if (syslog_identifier)
                        iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier);
        }

        static const char * const line_break_field_table[_LINE_BREAK_MAX] = {
                [LINE_BREAK_NEWLINE]    = NULL, /* Do not add field if traditional newline */
                [LINE_BREAK_NUL]        = "_LINE_BREAK=nul",
                [LINE_BREAK_LINE_MAX]   = "_LINE_BREAK=line-max",
                [LINE_BREAK_EOF]        = "_LINE_BREAK=eof",
                [LINE_BREAK_PID_CHANGE] = "_LINE_BREAK=pid-change",
        };

        const char *c = line_break_field_table[line_break];

        /* If this log message was generated due to an uncommon line break then mention this in the log
         * entry */
        if (c)
                iovec[n++] = IOVEC_MAKE_STRING(c);

        message = strjoin("MESSAGE=", p);
        if (message)
                iovec[n++] = IOVEC_MAKE_STRING(message);

        server_dispatch_message(s->server, iovec, n, m, s->context, NULL, priority, 0);
        return 0;
}

static int syslog_parse_priority_and_facility(const char *s) {
        int prio, r;

        /* Parses both facility and priority in one value, i.e. is different from log_level_from_string()
         * which only parses the priority and refuses any facility value */

        r = safe_atoi(s, &prio);
        if (r < 0)
                return r;

        if (prio < 0 || prio > 999)
                return -ERANGE;

        return prio;
}

static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
        char *orig;
        int r;

        assert(s);
        assert(p);

        orig = p;
        p = strstrip(p);

        /* line breaks by NUL, line max length or EOF are not permissible during the negotiation part of the protocol */
        if (line_break != LINE_BREAK_NEWLINE && s->state != STDOUT_STREAM_RUNNING)
                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
                                         "Control protocol line not properly terminated.");

        switch (s->state) {

        case STDOUT_STREAM_IDENTIFIER:
                if (!isempty(p)) {
                        s->identifier = strdup(p);
                        if (!s->identifier)
                                return log_oom();
                }

                s->state = STDOUT_STREAM_UNIT_ID;
                return 0;

        case STDOUT_STREAM_UNIT_ID:
                if (s->ucred.uid == 0 &&
                    unit_name_is_valid(p, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {

                        s->unit_id = strdup(p);
                        if (!s->unit_id)
                                return log_oom();
                }

                s->state = STDOUT_STREAM_PRIORITY;
                return 0;

        case STDOUT_STREAM_PRIORITY: {
                int priority;

                priority = syslog_parse_priority_and_facility(p);
                if (priority < 0)
                        return log_warning_errno(priority, "Failed to parse log priority line: %m");

                s->priority = priority;
                s->state = STDOUT_STREAM_LEVEL_PREFIX;
                return 0;
        }

        case STDOUT_STREAM_LEVEL_PREFIX:
                r = parse_boolean(p);
                if (r < 0)
                        return log_warning_errno(r, "Failed to parse level prefix line: %m");

                s->level_prefix = r;
                s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
                return 0;

        case STDOUT_STREAM_FORWARD_TO_SYSLOG:
                r = parse_boolean(p);
                if (r < 0)
                        return log_warning_errno(r, "Failed to parse forward to syslog line: %m");

                s->forward_to_syslog = r;
                s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
                return 0;

        case STDOUT_STREAM_FORWARD_TO_KMSG:
                r = parse_boolean(p);
                if (r < 0)
                        return log_warning_errno(r, "Failed to parse copy to kmsg line: %m");

                s->forward_to_kmsg = r;
                s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
                return 0;

        case STDOUT_STREAM_FORWARD_TO_CONSOLE:
                r = parse_boolean(p);
                if (r < 0)
                        return log_warning_errno(r, "Failed to parse copy to console line.");

                s->forward_to_console = r;
                s->state = STDOUT_STREAM_RUNNING;

                /* Try to save the stream, so that journald can be restarted and we can recover */
                (void) stdout_stream_save(s);
                return 0;

        case STDOUT_STREAM_RUNNING:
                return stdout_stream_log(s, orig, line_break);
        }

        assert_not_reached("Unknown stream state");
}

static int stdout_stream_found(
                StdoutStream *s,
                char *p,
                size_t l,
                LineBreak line_break) {

        char saved;
        int r;

        assert(s);
        assert(p);

        /* Let's NUL terminate the specified buffer for this call, and revert back afterwards */
        saved = p[l];
        p[l] = 0;
        r = stdout_stream_line(s, p, line_break);
        p[l] = saved;

        return r;
}

static size_t stdout_stream_line_max(StdoutStream *s) {
        assert(s);

        /* During the "setup" phase of our protocol, let's ensure we use a line length where a full unit name
         * can fit in */
        if (s->state != STDOUT_STREAM_RUNNING)
                return STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX;

        /* After the protocol's "setup" phase is complete, let's use whatever the user configured */
        return s->server->line_max;
}

static int stdout_stream_scan(
                StdoutStream *s,
                char *p,
                size_t remaining,
                LineBreak force_flush,
                size_t *ret_consumed) {

        size_t consumed = 0, line_max;
        int r;

        assert(s);
        assert(p);

        line_max = stdout_stream_line_max(s);

        for (;;) {
                LineBreak line_break;
                size_t skip, found;
                char *end1, *end2;
                size_t tmp_remaining = MIN(remaining, line_max);

                end1 = memchr(p, '\n', tmp_remaining);
                end2 = memchr(p, 0, end1 ? (size_t) (end1 - p) : tmp_remaining);

                if (end2) {
                        /* We found a NUL terminator */
                        found = end2 - p;
                        skip = found + 1;
                        line_break = LINE_BREAK_NUL;
                } else if (end1) {
                        /* We found a \n terminator */
                        found = end1 - p;
                        skip = found + 1;
                        line_break = LINE_BREAK_NEWLINE;
                } else if (remaining >= line_max) {
                        /* Force a line break after the maximum line length */
                        found = skip = line_max;
                        line_break = LINE_BREAK_LINE_MAX;
                } else
                        break;

                r = stdout_stream_found(s, p, found, line_break);
                if (r < 0)
                        return r;

                p += skip;
                consumed += skip;
                remaining -= skip;
        }

        if (force_flush >= 0 && remaining > 0) {
                r = stdout_stream_found(s, p, remaining, force_flush);
                if (r < 0)
                        return r;

                consumed += remaining;
        }

        if (ret_consumed)
                *ret_consumed = consumed;

        return 0;
}

static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
        size_t limit, consumed, allocated;
        StdoutStream *s = userdata;
        struct ucred *ucred;
        struct iovec iovec;
        ssize_t l;
        char *p;
        int r;

        struct msghdr msghdr = {
                .msg_iov = &iovec,
                .msg_iovlen = 1,
                .msg_control = &control,
                .msg_controllen = sizeof(control),
        };

        assert(s);

        if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
                log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
                goto terminate;
        }

        /* If the buffer is almost full, add room for another 1K */
        allocated = MALLOC_ELEMENTSOF(s->buffer);
        if (s->length + 512 >= allocated) {
                if (!GREEDY_REALLOC(s->buffer, s->length + 1 + 1024)) {
                        log_oom();
                        goto terminate;
                }

                allocated = MALLOC_ELEMENTSOF(s->buffer);
        }

        /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
         * always leave room for a terminating NUL we might need to add. */
        limit = MIN(allocated - 1, MAX(s->server->line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
        assert(s->length <= limit);
        iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);

        l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
        if (l < 0) {
                if (IN_SET(errno, EINTR, EAGAIN))
                        return 0;

                log_warning_errno(errno, "Failed to read from stream: %m");
                goto terminate;
        }
        cmsg_close_all(&msghdr);

        if (l == 0) {
                (void) stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_EOF, NULL);
                goto terminate;
        }

        /* Invalidate the context if the PID of the sender changed. This happens when a forked process
         * inherits stdout/stderr from a parent. In this case getpeercred() returns the ucred of the parent,
         * which can be invalid if the parent has exited in the meantime. */
        ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
        if (ucred && ucred->pid != s->ucred.pid) {
                /* Force out any previously half-written lines from a different process, before we switch to
                 * the new ucred structure for everything we just added */
                r = stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_PID_CHANGE, NULL);
                if (r < 0)
                        goto terminate;

                s->context = client_context_release(s->server, s->context);

                p = s->buffer + s->length;
        } else {
                p = s->buffer;
                l += s->length;
        }

        /* Always copy in the new credentials */
        if (ucred)
                s->ucred = *ucred;

        r = stdout_stream_scan(s, p, l, _LINE_BREAK_INVALID, &consumed);
        if (r < 0)
                goto terminate;

        /* Move what wasn't consumed to the front of the buffer */
        assert(consumed <= (size_t) l);
        s->length = l - consumed;
        memmove(s->buffer, p + consumed, s->length);

        return 1;

terminate:
        stdout_stream_destroy(s);
        return 0;
}

int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
        _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
        sd_id128_t id;
        int r;

        assert(s);
        assert(fd >= 0);

        r = sd_id128_randomize(&id);
        if (r < 0)
                return log_error_errno(r, "Failed to generate stream ID: %m");

        stream = new(StdoutStream, 1);
        if (!stream)
                return log_oom();

        *stream = (StdoutStream) {
                .fd = -1,
                .priority = LOG_INFO,
        };

        xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));

        r = getpeercred(fd, &stream->ucred);
        if (r < 0)
                return log_error_errno(r, "Failed to determine peer credentials: %m");

        r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
        if (r < 0)
                return log_error_errno(r, "SO_PASSCRED failed: %m");

        if (mac_selinux_use()) {
                r = getpeersec(fd, &stream->label);
                if (r < 0 && r != -EOPNOTSUPP)
                        (void) log_warning_errno(r, "Failed to determine peer security context: %m");
        }

        (void) shutdown(fd, SHUT_WR);

        r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
        if (r < 0)
                return log_error_errno(r, "Failed to add stream to event loop: %m");

        r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
        if (r < 0)
                return log_error_errno(r, "Failed to adjust stdout event source priority: %m");

        stream->fd = fd;

        stream->server = s;
        LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
        s->n_stdout_streams++;

        (void) server_start_or_stop_idle_timer(s); /* Maybe no longer idle? */

        if (ret)
                *ret = stream;

        TAKE_PTR(stream);
        return 0;
}

static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
        _cleanup_close_ int fd = -1;
        Server *s = userdata;
        int r;

        assert(s);

        if (revents != EPOLLIN)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "Got invalid event from epoll for stdout server fd: %" PRIx32,
                                       revents);

        fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
        if (fd < 0) {
                if (ERRNO_IS_ACCEPT_AGAIN(errno))
                        return 0;

                return log_error_errno(errno, "Failed to accept stdout connection: %m");
        }

        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
                struct ucred u;

                r = getpeercred(fd, &u);

                /* By closing fd here we make sure that the client won't wait too long for journald to
                 * gather all the data it adds to the error message to find out that the connection has
                 * just been refused.
                 */
                fd = safe_close(fd);

                server_driver_message(s, r < 0 ? 0 : u.pid, NULL, LOG_MESSAGE("Too many stdout streams, refusing connection."), NULL);
                return 0;
        }

        r = stdout_stream_install(s, fd, NULL);
        if (r < 0)
                return r;

        TAKE_FD(fd);
        return 0;
}

static int stdout_stream_load(StdoutStream *stream, const char *fname) {
        _cleanup_free_ char
                *priority = NULL,
                *level_prefix = NULL,
                *forward_to_syslog = NULL,
                *forward_to_kmsg = NULL,
                *forward_to_console = NULL,
                *stream_id = NULL;
        int r;

        assert(stream);
        assert(fname);

        if (!stream->state_file) {
                stream->state_file = path_join(stream->server->runtime_directory, "streams", fname);
                if (!stream->state_file)
                        return log_oom();
        }

        r = parse_env_file(NULL, stream->state_file,
                           "PRIORITY", &priority,
                           "LEVEL_PREFIX", &level_prefix,
                           "FORWARD_TO_SYSLOG", &forward_to_syslog,
                           "FORWARD_TO_KMSG", &forward_to_kmsg,
                           "FORWARD_TO_CONSOLE", &forward_to_console,
                           "IDENTIFIER", &stream->identifier,
                           "UNIT", &stream->unit_id,
                           "STREAM_ID", &stream_id);
        if (r < 0)
                return log_error_errno(r, "Failed to read: %s", stream->state_file);

        if (priority) {
                int p;

                p = syslog_parse_priority_and_facility(priority);
                if (p >= 0)
                        stream->priority = p;
        }

        if (level_prefix) {
                r = parse_boolean(level_prefix);
                if (r >= 0)
                        stream->level_prefix = r;
        }

        if (forward_to_syslog) {
                r = parse_boolean(forward_to_syslog);
                if (r >= 0)
                        stream->forward_to_syslog = r;
        }

        if (forward_to_kmsg) {
                r = parse_boolean(forward_to_kmsg);
                if (r >= 0)
                        stream->forward_to_kmsg = r;
        }

        if (forward_to_console) {
                r = parse_boolean(forward_to_console);
                if (r >= 0)
                        stream->forward_to_console = r;
        }

        if (stream_id) {
                sd_id128_t id;

                r = sd_id128_from_string(stream_id, &id);
                if (r >= 0)
                        xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));
        }

        return 0;
}

static int stdout_stream_restore(Server *s, const char *fname, int fd) {
        StdoutStream *stream;
        int r;

        assert(s);
        assert(fname);
        assert(fd >= 0);

        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
                log_warning("Too many stdout streams, refusing restoring of stream.");
                return -ENOBUFS;
        }

        r = stdout_stream_install(s, fd, &stream);
        if (r < 0)
                return r;

        stream->state = STDOUT_STREAM_RUNNING;
        stream->fdstore = true;

        /* Ignore all parsing errors */
        (void) stdout_stream_load(stream, fname);

        return 0;
}

int server_restore_streams(Server *s, FDSet *fds) {
        _cleanup_closedir_ DIR *d = NULL;
        struct dirent *de;
        const char *path;
        int r;

        path = strjoina(s->runtime_directory, "/streams");
        d = opendir(path);
        if (!d) {
                if (errno == ENOENT)
                        return 0;

                return log_warning_errno(errno, "Failed to enumerate %s: %m", path);
        }

        FOREACH_DIRENT(de, d, goto fail) {
                unsigned long st_dev, st_ino;
                bool found = false;
                int fd;

                if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
                        continue;

                FDSET_FOREACH(fd, fds) {
                        struct stat st;

                        if (fstat(fd, &st) < 0)
                                return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);

                        if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
                                found = true;
                                break;
                        }
                }

                if (!found) {
                        /* No file descriptor? Then let's delete the state file */
                        log_debug("Cannot restore stream file %s", de->d_name);
                        if (unlinkat(dirfd(d), de->d_name, 0) < 0)
                                log_warning_errno(errno, "Failed to remove %s/%s: %m", path, de->d_name);
                        continue;
                }

                fdset_remove(fds, fd);

                r = stdout_stream_restore(s, de->d_name, fd);
                if (r < 0)
                        safe_close(fd);
        }

        return 0;

fail:
        return log_error_errno(errno, "Failed to read streams directory: %m");
}

int server_open_stdout_socket(Server *s, const char *stdout_socket) {
        int r;

        assert(s);
        assert(stdout_socket);

        if (s->stdout_fd < 0) {
                union sockaddr_union sa;
                socklen_t sa_len;

                r = sockaddr_un_set_path(&sa.un, stdout_socket);
                if (r < 0)
                        return log_error_errno(r, "Unable to use namespace path %s for AF_UNIX socket: %m", stdout_socket);
                sa_len = r;

                s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
                if (s->stdout_fd < 0)
                        return log_error_errno(errno, "socket() failed: %m");

                (void) sockaddr_un_unlink(&sa.un);

                r = bind(s->stdout_fd, &sa.sa, sa_len);
                if (r < 0)
                        return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);

                (void) chmod(sa.un.sun_path, 0666);

                if (listen(s->stdout_fd, SOMAXCONN) < 0)
                        return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path);
        } else
                (void) fd_nonblock(s->stdout_fd, true);

        r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s);
        if (r < 0)
                return log_error_errno(r, "Failed to add stdout server fd to event source: %m");

        r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5);
        if (r < 0)
                return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");

        return 0;
}

void stdout_stream_send_notify(StdoutStream *s) {
        struct iovec iovec = {
                .iov_base = (char*) "FDSTORE=1",
                .iov_len = STRLEN("FDSTORE=1"),
        };
        struct msghdr msghdr = {
                .msg_iov = &iovec,
                .msg_iovlen = 1,
        };
        struct cmsghdr *cmsg;
        ssize_t l;

        assert(s);
        assert(!s->fdstore);
        assert(s->in_notify_queue);
        assert(s->server);
        assert(s->server->notify_fd >= 0);

        /* Store the connection fd in PID 1, so that we get it passed
         * in again on next start */

        msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
        msghdr.msg_control = alloca0(msghdr.msg_controllen);

        cmsg = CMSG_FIRSTHDR(&msghdr);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));

        memcpy(CMSG_DATA(cmsg), &s->fd, sizeof(int));

        l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAIT|MSG_NOSIGNAL);
        if (l < 0) {
                if (errno == EAGAIN)
                        return;

                log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m");
        } else {
                log_debug("Successfully sent stream file descriptor to service manager.");
                s->fdstore = 1;
        }

        LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
        s->in_notify_queue = false;

}
