journald-syslog.c revision e88baee88fad8bc59d33b55a7a2d640ef9e16cd6
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/***
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering This file is part of systemd.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Copyright 2011 Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is free software; you can redistribute it and/or modify it
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering under the terms of the GNU Lesser General Public License as published by
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering (at your option) any later version.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is distributed in the hope that it will be useful, but
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Lesser General Public License for more details.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering You should have received a copy of the GNU Lesser General Public License
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering***/
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include <unistd.h>
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <stddef.h>
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include <sys/epoll.h>
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering#include "systemd/sd-messages.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include "socket-util.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include "journald.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include "journald-syslog.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include "journald-kmsg.h"
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering#include "journald-console.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering/* Warn once every 30s if we missed syslog message */
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct msghdr msghdr;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct cmsghdr *cmsg;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering union {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct cmsghdr cmsghdr;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering } control;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering union sockaddr_union sa;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(s);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(iovec);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(n_iovec > 0);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering zero(msghdr);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_iov = (struct iovec*) iovec;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_iovlen = n_iovec;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering zero(sa);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering sa.un.sun_family = AF_UNIX;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_name = &sa;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (ucred) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering zero(control);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_control = &control;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_controllen = sizeof(control);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering cmsg = CMSG_FIRSTHDR(&msghdr);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering cmsg->cmsg_level = SOL_SOCKET;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering cmsg->cmsg_type = SCM_CREDENTIALS;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering msghdr.msg_controllen = cmsg->cmsg_len;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Forward the syslog message we received via /dev/log to
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * /run/systemd/syslog. Unfortunately we currently can't set
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * the SO_TIMESTAMP auxiliary data, and hence we don't. */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* The socket is full? I guess the syslog implementation is
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * too slow, and we shouldn't wait for that... */
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (errno == EAGAIN) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering s->n_forward_syslog_missed++;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (ucred && errno == ESRCH) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct ucred u;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Hmm, presumably the sender process vanished
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * by now, so let's fix it as good as we
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * can, and retry */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering u = *ucred;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering u.pid = getpid();
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (errno == EAGAIN) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering s->n_forward_syslog_missed++;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (errno != ENOENT)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_debug("Failed to forward syslog message: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic void forward_syslog_raw(Server *s, int priority, const char *buffer, struct ucred *ucred, struct timeval *tv) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct iovec iovec;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(s);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(buffer);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (LOG_PRI(priority) > s->max_level_syslog)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec, buffer);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering forward_syslog_iovec(s, &iovec, 1, ucred, tv);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringvoid server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct iovec iovec[5];
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char header_priority[6], header_time[64], header_pid[16];
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering int n = 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering time_t t;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct tm *tm;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char *ident_buf = NULL;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(s);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(priority >= 0);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(priority <= 999);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(message);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (LOG_PRI(priority) > s->max_level_syslog)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* First: priority field */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char_array_0(header_priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], header_priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Second: timestamp */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering tm = localtime(&t);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!tm)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], header_time);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Third: identifier and PID */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (ucred) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!identifier) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering get_process_comm(ucred->pid, &ident_buf);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering identifier = ident_buf;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char_array_0(header_pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (identifier)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], header_pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering } else if (identifier) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Fourth: message */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering forward_syslog_iovec(s, iovec, n, ucred, tv);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(ident_buf);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint syslog_fixup_facility(int priority) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((priority & LOG_FACMASK) == 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return (priority & LOG_PRIMASK) | LOG_USER;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return priority;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmeksize_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *p;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char *t;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering size_t l, e;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(buf);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering p = *buf;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering p += strspn(p, WHITESPACE);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering l = strcspn(p, WHITESPACE);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (l <= 0 ||
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering p[l-1] != ':')
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek return 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering e = l;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering l--;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (p[l-1] == ']') {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering size_t k = l-1;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering for (;;) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (p[k] == '[') {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering t = strndup(p+k+1, l-k-2);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (t)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *pid = t;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering l = k;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering break;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (k == 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering break;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering k--;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering t = strndup(p, l);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (t)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *identifier = t;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek e += strspn(p + e, WHITESPACE);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *buf = p + e;
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek return e;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringvoid syslog_parse_priority(char **p, int *priority) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering int a = 0, b = 0, c = 0;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering int k;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering assert(p);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering assert(*p);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering assert(priority);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if ((*p)[0] != '<')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!strchr(*p, '>'))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if ((*p)[2] == '>') {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering c = undecchar((*p)[1]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering k = 3;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } else if ((*p)[3] == '>') {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering b = undecchar((*p)[1]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering c = undecchar((*p)[2]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering k = 4;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } else if ((*p)[4] == '>') {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering a = undecchar((*p)[1]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering b = undecchar((*p)[2]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering c = undecchar((*p)[3]);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering k = 5;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } else
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (a < 0 || b < 0 || c < 0)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering *priority = a*100+b*10+c;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering *p += k;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering}
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringstatic void syslog_skip_date(char **buf) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering enum {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering LETTER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE_OR_NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering COLON
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } sequence[] = {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering LETTER, LETTER, LETTER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE_OR_NUMBER, NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE_OR_NUMBER, NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering COLON,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE_OR_NUMBER, NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering COLON,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE_OR_NUMBER, NUMBER,
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering SPACE
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering };
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering char *p;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering unsigned i;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering assert(buf);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering assert(*buf);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering p = *buf;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!*p)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering switch (sequence[i]) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering case SPACE:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (*p != ' ')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering break;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering case SPACE_OR_NUMBER:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (*p == ' ')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering break;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* fall through */
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering case NUMBER:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (*p < '0' || *p > '9')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering break;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering case LETTER:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!(*p >= 'A' && *p <= 'Z') &&
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering !(*p >= 'a' && *p <= 'z'))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering break;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering case COLON:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (*p != ':')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering break;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering }
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering }
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering *buf = p;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering}
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringvoid server_process_syslog_message(
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Server *s,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *buf,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct ucred *ucred,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct timeval *tv,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *label,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering size_t label_len) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct iovec iovec[N_IOVEC_META_FIELDS + 6];
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unsigned n = 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering int priority = LOG_USER | LOG_INFO;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering char *identifier = NULL, *pid = NULL;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *orig;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(s);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(buf);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering orig = buf;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering syslog_parse_priority((char**) &buf, &priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (s->forward_to_syslog)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering forward_syslog_raw(s, priority, orig, ucred, tv);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering syslog_skip_date((char**) &buf);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering syslog_parse_identifier(&buf, &identifier, &pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (s->forward_to_kmsg)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering server_forward_kmsg(s, priority, identifier, buf, ucred);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (s->forward_to_console)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering server_forward_console(s, priority, identifier, buf, ucred);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (priority & LOG_FACMASK)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (identifier) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (syslog_identifier)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (pid) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering syslog_pid = strappend("SYSLOG_PID=", pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (syslog_pid)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering message = strappend("MESSAGE=", buf);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (message)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(message);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(syslog_priority);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(syslog_facility);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(syslog_identifier);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering free(syslog_pid);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint server_open_syslog_socket(Server *s) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering union sockaddr_union sa;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering int one, r;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering struct epoll_event ev;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering assert(s);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (s->syslog_fd < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (s->syslog_fd < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_error("socket() failed: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return -errno;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering zero(sa);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering sa.un.sun_family = AF_UNIX;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unlink(sa.un.sun_path);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (r < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_error("bind() failed: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return -errno;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering chmod(sa.un.sun_path, 0666);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering } else
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering fd_nonblock(s->syslog_fd, 1);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering one = 1;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (r < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_error("SO_PASSCRED failed: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return -errno;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#ifdef HAVE_SELINUX
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering one = 1;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (r < 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_warning("SO_PASSSEC failed: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#endif
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering one = 1;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (r < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_error("SO_TIMESTAMP failed: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return -errno;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering zero(ev);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering ev.events = EPOLLIN;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering ev.data.fd = s->syslog_fd;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering log_error("Failed to add syslog server fd to epoll object: %m");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return -errno;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering }
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering}
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poetteringvoid server_maybe_warn_forward_syslog_missed(Server *s) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering usec_t n;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering assert(s);
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (s->n_forward_syslog_missed <= 0)
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering return;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering n = now(CLOCK_MONOTONIC);
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering return;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, "Forwarding to syslog missed %u messages.", s->n_forward_syslog_missed);
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering s->n_forward_syslog_missed = 0;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering s->last_warn_forward_syslog_missed = n;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering}