journald.c revision fe6521272ba203ec8f0d5a94f0729960b3f90525
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/***
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2011 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is free software; you can redistribute it and/or modify it
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering under the terms of the GNU General Public License as published by
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering the Free Software Foundation; either version 2 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering General Public License for more details.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering You should have received a copy of the GNU General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering***/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <sys/epoll.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <sys/socket.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <errno.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <sys/signalfd.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <unistd.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <fcntl.h>
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering#include <sys/acl.h>
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering#include <acl/libacl.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <stddef.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <sys/ioctl.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <linux/sockios.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "hashmap.h"
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering#include "journal-file.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "sd-daemon.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "socket-util.h"
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering#include "acl-util.h"
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering#include "cgroup-util.h"
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering#include "list.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering#define USER_JOURNALS_MAX 1024
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering#define STDOUT_STREAMS_MAX 4096
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringtypedef struct StdoutStream StdoutStream;
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringtypedef struct Server {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int epoll_fd;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int signal_fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int syslog_fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int native_fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int stdout_fd;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering JournalFile *runtime_journal;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *system_journal;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Hashmap *user_journals;
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering uint64_t seqnum;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *buffer;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering size_t buffer_size;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering JournalMetrics metrics;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering uint64_t max_use;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering bool compress;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LIST_HEAD(StdoutStream, stdout_streams);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering unsigned n_stdout_streams;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering} Server;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringtypedef enum StdoutStreamState {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering STDOUT_STREAM_TAG,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering STDOUT_STREAM_PRIORITY,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering STDOUT_STREAM_PRIORITY_PREFIX,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering STDOUT_STREAM_TEE_CONSOLE,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering STDOUT_STREAM_RUNNING
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering} StdoutStreamState;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstruct StdoutStream {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering Server *server;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering StdoutStreamState state;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct ucred ucred;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char *tag;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int priority;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering bool priority_prefix:1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering bool tee_console:1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char buffer[LINE_MAX+1];
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering size_t length;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering};
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poetteringstatic void fix_perms(JournalFile *f, uid_t uid) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_t acl;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_entry_t entry;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_permset_t permset;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering int r;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering assert(f);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = fchmod_and_fchown(f->fd, 0640, 0, 0);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (uid <= 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl = acl_get_fd(f->fd);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (!acl) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = acl_find_uid(acl, uid, &entry);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r <= 0) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (acl_create_entry(&acl, &entry) < 0 ||
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_set_tag_type(entry, ACL_USER) < 0 ||
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_set_qualifier(entry, &uid) < 0) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering goto finish;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (acl_get_permset(entry, &permset) < 0 ||
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_add_perm(permset, ACL_READ) < 0 ||
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_calc_mask(&acl) < 0) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering goto finish;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (acl_set_fd(f->fd, acl) < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poetteringfinish:
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering acl_free(acl);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering}
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poetteringstatic JournalFile* find_journal(Server *s, uid_t uid) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering char *p;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering int r;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering JournalFile *f;
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering char ids[33];
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering sd_id128_t machine;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering assert(s);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering /* We split up user logs only on /var, not on /run */
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (!s->system_journal)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return s->runtime_journal;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (uid <= 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return s->system_journal;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering r = sd_id128_get_machine(&machine);
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering if (r < 0)
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering return s->system_journal;
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (f)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return f;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering if (asprintf(&p, "/var/log/journal/%s/user-%lu.journal", sd_id128_to_string(machine, ids), (unsigned long) uid) < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return s->system_journal;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering /* Too many open? Then let's close one */
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering f = hashmap_steal_first(s->user_journals);
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering assert(f);
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering journal_file_close(f);
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering }
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering r = journal_file_open(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering free(p);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return s->system_journal;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering fix_perms(f, uid);
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering f->metrics = s->metrics;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering f->compress = s->compress;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering journal_file_close(f);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return s->system_journal;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return f;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering}
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poetteringstatic void server_vacuum(Server *s) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering Iterator i;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering void *k;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering char *p;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering char ids[33];
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering sd_id128_t machine;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering int r;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering JournalFile *f;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_info("Rotating...");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (s->runtime_journal) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = journal_file_rotate(&s->runtime_journal);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (s->system_journal) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = journal_file_rotate(&s->system_journal);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = journal_file_rotate(&f);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to rotate %s: %s", f->path, strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering else
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering hashmap_replace(s->user_journals, k, f);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_info("Vacuuming...");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = sd_id128_get_machine(&machine);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to get machine ID: %s", strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (asprintf(&p, "/var/log/journal/%s", sd_id128_to_string(machine, ids)) < 0) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Out of memory.");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = journal_directory_vacuum(p, s->max_use, s->metrics.keep_free);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0 && r != -ENOENT)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering free(p);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (asprintf(&p, "/run/log/journal/%s", ids) < 0) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Out of memory.");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = journal_directory_vacuum(p, s->max_use, s->metrics.keep_free);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0 && r != -ENOENT)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering free(p);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering}
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic void dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *pid = NULL, *uid = NULL, *gid = NULL,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *source_time = NULL, *boot_id = NULL, *machine_id = NULL,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *comm = NULL, *cmdline = NULL, *hostname = NULL,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *audit_session = NULL, *audit_loginuid = NULL,
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering *exe = NULL, *cgroup = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering char idbuf[33];
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_id128_t id;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering char *t;
de190aef08bb267b645205a747762df573b36834Lennart Poettering uid_t loginuid = 0, realuid = 0;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering JournalFile *f;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering bool vacuumed = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(iovec || n == 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (n == 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(n + 13 <= m);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (ucred) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint32_t session;
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering char *path;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poettering realuid = ucred->uid;
de190aef08bb267b645205a747762df573b36834Lennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], pid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], uid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], gid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = get_process_comm(ucred->pid, &t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering comm = strappend("_COMM=", t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (comm)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], comm);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = get_process_exe(ucred->pid, &t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering exe = strappend("_EXE=", t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (comm)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], exe);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering cmdline = strappend("_CMDLINE=", t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (cmdline)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], cmdline);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = audit_session_from_pid(ucred->pid, &session);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0)
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) session) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], audit_session);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = audit_loginuid_from_pid(ucred->pid, &loginuid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0)
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], audit_loginuid);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, ucred->pid, &path);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering if (r >= 0) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering cgroup = strappend("_SYSTEMD_CGROUP=", path);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering if (cgroup)
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering IOVEC_SET_STRING(iovec[n++], cgroup);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering free(path);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (tv) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) timeval_load(tv)) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], source_time);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering /* Note that strictly speaking storing the boot id here is
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering * redundant since the entry includes this in-line
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering * anyway. However, we need this indexed, too. */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_id128_get_boot(&id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0)
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], boot_id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_id128_get_machine(&id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r >= 0)
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], machine_id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering t = gethostname_malloc();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (t) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering hostname = strappend("_HOSTNAME=", t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (hostname)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering IOVEC_SET_STRING(iovec[n++], hostname);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(t);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(n <= m);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poetteringretry:
de190aef08bb267b645205a747762df573b36834Lennart Poettering f = find_journal(s, realuid == 0 ? 0 : loginuid);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (!f)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_warning("Dropping message, as we can't find a place to store the data.");
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering else {
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r == -E2BIG && !vacuumed) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_info("Allocation limit reached.");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering server_vacuum(s);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering vacuumed = true;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_info("Retrying write.");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering goto retry;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_error("Failed to write entry, ignoring: %s", strerror(-r));
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(pid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(uid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(gid);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(comm);
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering free(exe);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(cmdline);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(source_time);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(boot_id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(machine_id);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(hostname);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(audit_session);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(audit_loginuid);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(cgroup);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic void process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec iovec[16];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering unsigned n = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int priority = LOG_USER | LOG_INFO;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(buf);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering parse_syslog_priority((char**) &buf, &priority);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering skip_syslog_date((char**) &buf);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering message = strappend("MESSAGE=", buf);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (message)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(iovec[n++], message);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(message);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(syslog_facility);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(syslog_priority);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poetteringstatic bool valid_user_field(const char *p, size_t l) {
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering const char *a;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* We kinda enforce POSIX syntax recommendations for
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering environment variables here, but make a couple of additional
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering requirements.
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* No empty field names */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (l <= 0)
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return false;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* Don't allow names longer than 64 chars */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (l > 64)
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return false;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* Variables starting with an underscore are protected */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (p[0] == '_')
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return false;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* Don't allow digits as first character */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (p[0] >= '0' && p[0] <= '9')
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return false;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* Only allow A-Z0-9 and '_' */
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering for (a = p; a < p + l; a++)
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (!((*a >= 'A' && *a <= 'Z') ||
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering (*a >= '0' && *a <= '9') ||
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering *a == '_'))
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return false;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering return true;
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering}
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic void process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec *iovec = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering unsigned n = 0, m = 0, j;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering const char *p;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering size_t remaining;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(buffer || n == 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering p = buffer;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering remaining = buffer_size;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering while (remaining > 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering const char *e, *q;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering e = memchr(p, '\n', remaining);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!e) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* Trailing noise, let's ignore it, and flush what we collected */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_debug("Received message with trailing noise, ignoring.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (e == p) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* Entry separator */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dispatch_message(s, iovec, n, m, ucred, tv);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering n = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering p++;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering remaining--;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (*p == '.' || *p == '#') {
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering /* Ignore control commands for now, and
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering * comments too. */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering remaining -= (e - p) + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering p = e + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* A property follows */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (n+13 >= m) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec *c;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering unsigned u;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering u = MAX((n+13U) * 2U, 4U);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering c = realloc(iovec, u * sizeof(struct iovec));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!c) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Out of memory");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering iovec = c;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering m = u;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering q = memchr(p, '=', e - p);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (q) {
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (valid_user_field(p, q - p)) {
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering /* If the field name starts with an
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering * underscore, skip the variable,
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering * since that indidates a trusted
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering * field */
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering iovec[n].iov_base = (char*) p;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering iovec[n].iov_len = e - p;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering n++;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering remaining -= (e - p) + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering p = e + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering uint64_t l;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *k;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_debug("Failed to parse message, ignoring.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering memcpy(&l, e + 1, sizeof(uint64_t));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = le64toh(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering e[1+sizeof(uint64_t)+l] != '\n') {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_debug("Failed to parse message, ignoring.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering k = malloc((e - p) + 1 + l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!k) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Out of memory");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering memcpy(k, p, e - p);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering k[e - p] = '=';
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering if (valid_user_field(p, e - p)) {
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering iovec[n].iov_base = k;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering iovec[n].iov_len = (e - p) + 1 + l;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering n++;
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering } else
2b0ba69bb127b6b1d76512ce32fc9cfd89670f97Lennart Poettering free(k);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering p = e + 1 + sizeof(uint64_t) + l + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dispatch_message(s, iovec, n, m, ucred, tv);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering for (j = 0; j < n; j++)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (iovec[j].iov_base < buffer ||
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(iovec[j].iov_base);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p, size_t l) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct iovec iovec[15];
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char *message = NULL, *syslog_priority = NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering unsigned n = 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering size_t tag_len;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int priority;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(p);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering priority = s->priority;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->priority_prefix &&
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l > 3 &&
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p[0] == '<' &&
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p[1] >= '0' && p[1] <= '7' &&
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p[2] == '>') {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering priority = p[1] - '0';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p += 3;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l -= 3;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l <= 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (asprintf(&syslog_priority, "PRIORITY=%i", priority) >= 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering tag_len = s->tag ? strlen(s->tag) + 2: 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering message = malloc(8 + tag_len + l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (message) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memcpy(message, "MESSAGE=", 8);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->tag) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memcpy(message+8, s->tag, tag_len-2);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memcpy(message+8+tag_len-2, ": ", 2);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memcpy(message+8+tag_len, p, l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering iovec[n].iov_base = message;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering iovec[n].iov_len = 8+tag_len+l;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering n++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->tee_console) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int console;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering console = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (console >= 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering n = 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->tag) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering IOVEC_SET_STRING(iovec[n++], s->tag);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering iovec[n].iov_base = (void*) p;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering iovec[n].iov_len = l;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering n++;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering IOVEC_SET_STRING(iovec[n++], (char*) "\n");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering writev(console, iovec, n);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(message);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(syslog_priority);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int stdout_stream_line(StdoutStream *s, const char *p, size_t l) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(p);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering while (l > 0 && strchr(WHITESPACE, *p)) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l--;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p++;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering while (l > 0 && strchr(WHITESPACE, *(p+l-1)))
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l--;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering switch (s->state) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering case STDOUT_STREAM_TAG:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l > 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->tag = strndup(p, l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!s->tag) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Out of memory");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->state = STDOUT_STREAM_PRIORITY;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering case STDOUT_STREAM_PRIORITY:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l != 1 || *p < '0' || *p > '7') {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_warning("Failed to parse log priority line.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->priority = *p - '0';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->state = STDOUT_STREAM_PRIORITY_PREFIX;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering case STDOUT_STREAM_PRIORITY_PREFIX:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l != 1 || *p < '0' || *p > '1') {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_warning("Failed to parse priority prefix line.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->priority_prefix = *p - '0';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->state = STDOUT_STREAM_TEE_CONSOLE;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering case STDOUT_STREAM_TEE_CONSOLE:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l != 1 || *p < '0' || *p > '1') {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_warning("Failed to parse tee to console line.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->tee_console = *p - '0';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->state = STDOUT_STREAM_RUNNING;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering case STDOUT_STREAM_RUNNING:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return stdout_stream_log(s, p, l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert_not_reached("Unknown stream state");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char *p;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering size_t remaining;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p = s->buffer;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering remaining = s->length;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering for (;;) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char *end;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering size_t skip;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering end = memchr(p, '\n', remaining);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!end) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (remaining >= LINE_MAX) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering end = p + LINE_MAX;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering skip = LINE_MAX;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering break;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering skip = end - p + 1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = stdout_stream_line(s, p, end - p);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering remaining -= skip;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p += skip;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (force_flush && remaining > 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = stdout_stream_line(s, p, remaining);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering p += remaining;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering remaining = 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (p > s->buffer) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memmove(s->buffer, p, remaining);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->length = remaining;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int stdout_stream_process(StdoutStream *s) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ssize_t l;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (errno == EAGAIN)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_warning("Failed to read from stream: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l == 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = stdout_stream_scan(s, true);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->length += l;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = stdout_stream_scan(s, false);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic void stdout_stream_free(StdoutStream *s) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->server) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s->server->n_stdout_streams > 0);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->server->n_stdout_streams --;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->fd >= 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->server)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(s->fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(s->tag);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int stdout_stream_new(Server *s) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering StdoutStream *stream;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int fd, r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering socklen_t len;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct epoll_event ev;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (fd < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (errno == EAGAIN)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to accept stdout connection: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_warning("Too many stdout streams, refusing connection.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stream = new0(StdoutStream, 1);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!stream) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Out of memory.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -ENOMEM;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stream->fd = fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering len = sizeof(stream->ucred);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to determine peer credentials: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto fail;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (shutdown(fd, SHUT_WR) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to shutdown writing side of socket: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto fail;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(ev);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.data.ptr = stream;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.events = EPOLLIN;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to add stream to event loop: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto fail;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stream->server = s;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->n_stdout_streams ++;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringfail:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stdout_stream_free(stream);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int process_event(Server *s, struct epoll_event *ev) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (ev->data.fd == s->signal_fd) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct signalfd_siginfo sfsi;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering ssize_t n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (ev->events != EPOLLIN) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_info("Got invalid event from epoll.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EIO;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = read(s->signal_fd, &sfsi, sizeof(sfsi));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n != sizeof(sfsi)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EIO;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (errno == EINTR || errno == EAGAIN)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_debug("Received SIG%s", signal_to_string(sfsi.ssi_signo));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else if (ev->data.fd == s->native_fd ||
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev->data.fd == s->syslog_fd) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (ev->events != EPOLLIN) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_info("Got invalid event from epoll.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EIO;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (;;) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct msghdr msghdr;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct iovec iovec;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct ucred *ucred = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct timeval *tv = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct cmsghdr *cmsg;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering union {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct cmsghdr cmsghdr;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering CMSG_SPACE(sizeof(struct timeval))];
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } control;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering ssize_t n;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int v;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("SIOCINQ failed: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (v <= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->buffer_size < (size_t) v) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering void *b;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering size_t l;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering b = realloc(s->buffer, l+1);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!b) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Couldn't increase buffer.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOMEM;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->buffer_size = l;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->buffer = b;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering zero(iovec);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering iovec.iov_base = s->buffer;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering iovec.iov_len = s->buffer_size;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering zero(control);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering zero(msghdr);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering msghdr.msg_iov = &iovec;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering msghdr.msg_iovlen = 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering msghdr.msg_control = &control;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering msghdr.msg_controllen = sizeof(control);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (errno == EINTR || errno == EAGAIN)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("recvmsg() failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (cmsg->cmsg_level == SOL_SOCKET &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering cmsg->cmsg_type == SCM_CREDENTIALS &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering ucred = (struct ucred*) CMSG_DATA(cmsg);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else if (cmsg->cmsg_level == SOL_SOCKET &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering cmsg->cmsg_type == SO_TIMESTAMP &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering tv = (struct timeval*) CMSG_DATA(cmsg);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (ev->data.fd == s->syslog_fd) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *e;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering e = memchr(s->buffer, '\n', n);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (e)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *e = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering else
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->buffer[n] = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering process_syslog_message(s, strstrip(s->buffer), ucred, tv);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering process_native_message(s, s->buffer, n, ucred, tv);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering return 1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else if (ev->data.fd == s->stdout_fd) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (ev->events != EPOLLIN) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_info("Got invalid event from epoll.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EIO;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stdout_stream_new(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 1;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering StdoutStream *stream;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_info("Got invalid event from epoll.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EIO;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering /* If it is none of the well-known fds, it must be an
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering * stdout stream fd. Note that this is a bit ugly here
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering * (since we rely that none of the well-known fds
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering * could be interpreted as pointer), but nonetheless
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering * safe, since the well-known fds would never get an
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering * fd > 4096, i.e. beyond the first memory page */
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stream = ev->data.ptr;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (stdout_stream_process(stream) <= 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stdout_stream_free(stream);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering log_error("Unknown event.");
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poetteringstatic int system_journal_open(Server *s) {
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering int r;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering char *fn;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering sd_id128_t machine;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering char ids[33];
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering r = sd_id128_get_machine(&machine);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (r < 0)
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering return r;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering /* First try to create the machine path, but not the prefix */
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering fn = strappend("/var/log/journal/", sd_id128_to_string(machine, ids));
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (!fn)
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering return -ENOMEM;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering (void) mkdir(fn, 0755);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering free(fn);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering /* The create the system journal file */
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering fn = join("/var/log/journal/", ids, "/system.journal", NULL);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (!fn)
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering return -ENOMEM;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering free(fn);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering if (r >= 0) {
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering s->system_journal->metrics = s->metrics;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering s->system_journal->compress = s->compress;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering fix_perms(s->system_journal, 0);
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering return r;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering }
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (r < 0 && r != -ENOENT) {
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering log_error("Failed to open system journal: %s", strerror(-r));
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering return r;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering }
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering /* /var didn't work, so try /run, but this time we
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering * create the prefix too */
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering fn = join("/run/log/journal/", ids, "/system.journal", NULL);
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering if (!fn)
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering return -ENOMEM;
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering (void) mkdir_parents(fn, 0755);
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal);
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering free(fn);
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering if (r < 0) {
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering log_error("Failed to open runtime journal: %s", strerror(-r));
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering return r;
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering }
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering s->runtime_journal->metrics = s->metrics;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering s->runtime_journal->compress = s->compress;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering fix_perms(s->runtime_journal, 0);
250d54b5bee6a46fe1c1626211e3a7e238eda628Lennart Poettering return r;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering}
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int open_syslog_socket(Server *s) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering union sockaddr_union sa;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int one, r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct epoll_event ev;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(s);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->syslog_fd < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->syslog_fd < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("socket() failed: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering zero(sa);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sa.un.sun_family = AF_UNIX;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strncpy(sa.un.sun_path, "/run/systemd/syslog", sizeof(sa.un.sun_path));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering unlink(sa.un.sun_path);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("bind() failed: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering chmod(sa.un.sun_path, 0666);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering one = 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("SO_PASSCRED failed: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering one = 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("SO_TIMESTAMP failed: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(ev);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.events = EPOLLIN;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.data.fd = s->syslog_fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to add syslog server fd to epoll object: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int open_native_socket(Server*s) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering union sockaddr_union sa;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int one, r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct epoll_event ev;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->native_fd < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->native_fd < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("socket() failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering zero(sa);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sa.un.sun_family = AF_UNIX;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strncpy(sa.un.sun_path, "/run/systemd/journal", sizeof(sa.un.sun_path));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unlink(sa.un.sun_path);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("bind() failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering chmod(sa.un.sun_path, 0666);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering one = 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("SO_PASSCRED failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering one = 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("SO_TIMESTAMP failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(ev);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.events = EPOLLIN;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.data.fd = s->native_fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to add native server fd to epoll object: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int open_stdout_socket(Server *s) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering union sockaddr_union sa;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct epoll_event ev;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->stdout_fd < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->stdout_fd < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("socket() failed: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(sa);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering sa.un.sun_family = AF_UNIX;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering strncpy(sa.un.sun_path, "/run/systemd/stdout", sizeof(sa.un.sun_path));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering unlink(sa.un.sun_path);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("bind() failed: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering chmod(sa.un.sun_path, 0666);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (listen(s->stdout_fd, SOMAXCONN) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("liste() failed: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(ev);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.events = EPOLLIN;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.data.fd = s->stdout_fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to add stdout server fd to epoll object: %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int open_signalfd(Server *s) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sigset_t mask;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct epoll_event ev;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert_se(sigemptyset(&mask) == 0);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering sigset_add_many(&mask, SIGINT, SIGTERM, -1);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->signal_fd < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("signalfd(): %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(ev);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.events = EPOLLIN;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ev.data.fd = s->signal_fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("epoll_ctl(): %m");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int server_init(Server *s) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int n, r, fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering zero(*s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = -1;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering s->metrics.max_size = DEFAULT_MAX_SIZE;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering s->metrics.min_size = DEFAULT_MIN_SIZE;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering s->metrics.keep_free = DEFAULT_KEEP_FREE;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering s->max_use = DEFAULT_MAX_USE;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering s->compress = true;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!s->user_journals) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Out of memory.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -ENOMEM;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->epoll_fd < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Failed to create epoll object: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering n = sd_listen_fds(true);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (n < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return n;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/native", 0) > 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->native_fd >= 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Too many native sockets passed.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->native_fd = fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/stdout", 0) > 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->stdout_fd >= 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Too many stdout sockets passed.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->stdout_fd = fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->syslog_fd >= 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Too many /dev/log sockets passed.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s->syslog_fd = fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Unknown socket passed.");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = open_syslog_socket(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = open_native_socket(s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = open_stdout_socket(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering r = system_journal_open(s);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = open_signalfd(s);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void server_done(Server *s) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(s);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering while (s->stdout_streams)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering stdout_stream_free(s->stdout_streams);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (s->system_journal)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering journal_file_close(s->system_journal);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (s->runtime_journal)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering journal_file_close(s->runtime_journal);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while ((f = hashmap_steal_first(s->user_journals)))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering journal_file_close(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering hashmap_free(s->user_journals);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (s->epoll_fd >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(s->epoll_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (s->signal_fd >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(s->signal_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (s->syslog_fd >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(s->syslog_fd);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->native_fd >= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering close_nointr_nofail(s->native_fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (s->stdout_fd >= 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(s->stdout_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringint main(int argc, char *argv[]) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Server server;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* if (getppid() != 1) { */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* log_error("This program should be invoked by init only."); */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* return EXIT_FAILURE; */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* } */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (argc > 1) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("This program does not take arguments.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return EXIT_FAILURE;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering log_set_target(LOG_TARGET_CONSOLE);
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering log_set_max_level(LOG_DEBUG);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_parse_environment();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_open();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering umask(0022);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = server_init(&server);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto finish;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_debug("systemd-journald running as pid %lu", (unsigned long) getpid());
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_notify(false,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering "READY=1\n"
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering "STATUS=Processing requests...");
50f20cfdb0f127e415ab38c024d9ca7a3602f74bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (;;) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering struct epoll_event event;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = epoll_wait(server.epoll_fd, &event, 1, -1);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (errno == EINTR)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering continue;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("epoll_wait() failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto finish;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (r == 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = process_event(&server, &event);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto finish;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else if (r == 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringfinish:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_notify(false,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering "STATUS=Shutting down...");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering server_done(&server);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}