journal-remote.c revision f53f7c8fc43df4e38655f2a1f57777c5934fee06
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2012 Zbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define REMOTE_JOURNAL_PATH "/var/log/journal/remote"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-remote.pem"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#define CERT_FILE CERTIFICATE_ROOT "/certs/journal-remote.pem"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#define TRUST_FILE CERTIFICATE_ROOT "/ca/trusted.pem"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int arg_compress = true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int arg_seal = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int http_socket = -1, https_socket = -1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic JournalWriteSplitMode arg_split_mode = JOURNAL_WRITE_SPLIT_HOST;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmekstatic bool arg_trust_all = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/**********************************************************************
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering **********************************************************************
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering **********************************************************************/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int spawn_child(const char* child, char** argv) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_error_errno(errno, "Failed to create pager pipe: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(errno, "Failed to fork: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* In the child */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error_errno(errno, "Failed to dup pipe to stdout: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Make sure the child goes away when the parent dies */
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Check whether our parent died before we were able
13790add4bf648fed816361794d8277a75253410Lennart Poettering * to set the death signal */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error_errno(errno, "Failed to exec child %s: %m", child);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_warning_errno(errno, "Failed to close write end of pipe: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering "--show-error",
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error_errno(errno, "Failed to spawn curl: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int spawn_getter(const char *getter, const char *url) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = strv_split_quoted(&words, getter, false);
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to split getter option: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to create command line: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error_errno(errno, "Failed to spawn getter %s: %m", getter);
13790add4bf648fed816361794d8277a75253410Lennart Poettering#define filename_escape(s) xescape((s), "/ ")
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int open_output(Writer *w, const char* host) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering output = arg_output ?: REMOTE_JOURNAL_PATH "/remote.journal";
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = asprintf(&_output, "%s/remote-%s.journal",
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error_errno(r, "Failed to open output journal %s: %m",
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Opened output file %s", w->journal->path);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering/**********************************************************************
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering **********************************************************************
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering **********************************************************************/
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int init_writer_hashmap(RemoteServer *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering static const struct hash_ops *hash_ops[] = {
13790add4bf648fed816361794d8277a75253410Lennart Poettering [JOURNAL_WRITE_SPLIT_HOST] = &string_hash_ops,
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(arg_split_mode >= 0 && arg_split_mode < (int) ELEMENTSOF(hash_ops));
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering s->writers = hashmap_new(hash_ops[arg_split_mode]);
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int get_writer(RemoteServer *s, const char *host,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (arg_split_mode == JOURNAL_WRITE_SPLIT_HOST) {
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek r = hashmap_put(s->writers, w->hashmap_key ?: key, w);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/**********************************************************************
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering **********************************************************************
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering **********************************************************************/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/* This should go away as soon as µhttpd allows state to be passed around. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int dispatch_raw_source_event(sd_event_source *event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int dispatch_blocking_source_event(sd_event_source *event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int dispatch_raw_connection_event(sd_event_source *event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int dispatch_http_event(sd_event_source *event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int get_source_for_fd(RemoteServer *s,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int fd, char *name, RemoteSource **source) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* This takes ownership of name, but only on success. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!GREEDY_REALLOC0(s->sources, s->sources_size, fd + 1))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_warning_errno(r, "Failed to get writer for source %s: %m",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->sources[fd] = source_new(fd, false, name, writer);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int remove_source(RemoteServer *s, int fd) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(fd >= 0 && fd < (ssize_t) s->sources_size);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* this closes fd too */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* This takes ownership of name, even on failure, if own_name is true. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = get_source_for_fd(s, fd, name, &source);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(r, "Failed to create source for fd:%d (%s): %m",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_add_io(s->events, &source->event,
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_add_defer(s->events, &source->event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering sd_event_source_set_enabled(source->event, SD_EVENT_ON);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(r, "Failed to register event source for fd:%d: %m",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_source_set_description(source->event, name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(r, "Failed to set source name for fd:%d: %m", fd);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int add_raw_socket(RemoteServer *s, int fd) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char name[sizeof("raw-socket-")-1 + DECIMAL_STR_MAX(int) + 1];
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_add_io(s->events, &s->listen_event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_source_set_description(s->listen_event, name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int setup_raw_socket(RemoteServer *s, const char *address) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/**********************************************************************
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering **********************************************************************
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering **********************************************************************/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int request_meta(void **connection_cls, int fd, char *hostname) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = get_writer(server, hostname, &writer);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_warning_errno(r, "Failed to get writer for source %s: %m",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering source = source_new(fd, true, hostname, writer);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering log_debug("Added RemoteSource as connection metadata %p", source);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Cleaning up connection metadata %p", s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_trace("%s: connection %p, %zu bytes",
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek __func__, connection, *upload_data_size);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_trace("Received %zu bytes", *upload_data_size);
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = push_data(source, upload_data, *upload_data_size);
13790add4bf648fed816361794d8277a75253410Lennart Poettering while (true) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = process_source(source, arg_compress, arg_seal);
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (r < 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_warning("Failed to process data for connection %p", connection);
13790add4bf648fed816361794d8277a75253410Lennart Poettering "Entry is too large, maximum is %u bytes.\n",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* The upload is finished */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_warning("Premature EOFbyte. %zu bytes lost.", remaining);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return mhd_respondf(connection, MHD_HTTP_EXPECTATION_FAILED,
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "Premature EOF. %zu bytes of trailing data not processed.",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.\n");
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_trace("Handling a connection %s %s %s", method, url, version);
13790add4bf648fed816361794d8277a75253410Lennart Poettering return mhd_respond(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "Unsupported method.\n");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return mhd_respond(connection, MHD_HTTP_NOT_FOUND,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering "Not found.\n");
13790add4bf648fed816361794d8277a75253410Lennart Poettering header = MHD_lookup_connection_value(connection,
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!header || !streq(header, "application/vnd.fdo.journal"))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "Content-Type: application/vnd.fdo.journal"
13790add4bf648fed816361794d8277a75253410Lennart Poettering " is required.\n");
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("MHD_get_connection_info failed: cannot get remote fd");
13790add4bf648fed816361794d8277a75253410Lennart Poettering return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "Cannot check remote address");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering r = check_permissions(connection, &code, &hostname);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering "Cannot check remote hostname");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = request_meta(connection_cls, fd, hostname);
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int setup_microhttpd_server(RemoteServer *s,
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *trust) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free},
13790add4bf648fed816361794d8277a75253410Lennart Poettering { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger},
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to make fd:%d nonblocking: %m", fd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering opts[opts_pos++] = (struct MHD_OptionItem)
13790add4bf648fed816361794d8277a75253410Lennart Poettering {MHD_OPTION_HTTPS_MEM_KEY, 0, (char*) key};
13790add4bf648fed816361794d8277a75253410Lennart Poettering opts[opts_pos++] = (struct MHD_OptionItem)
13790add4bf648fed816361794d8277a75253410Lennart Poettering {MHD_OPTION_HTTPS_MEM_CERT, 0, (char*) cert};
13790add4bf648fed816361794d8277a75253410Lennart Poettering opts[opts_pos++] = (struct MHD_OptionItem)
13790add4bf648fed816361794d8277a75253410Lennart Poettering {MHD_OPTION_HTTPS_MEM_TRUST, 0, (char*) trust};
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("Failed to start µhttp daemon");
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Started MHD %s daemon on fd:%d (wrapper @ %p)",
13790add4bf648fed816361794d8277a75253410Lennart Poettering info = MHD_get_daemon_info(d->daemon, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("µhttp returned NULL daemon info");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_add_io(s->events, &d->event,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(r, "Failed to add event callback: %m");
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek r = sd_event_source_set_description(d->event, "epoll-fd");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(r, "Failed to set source name: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = hashmap_ensure_allocated(&s->daemons, &uint64_hash_ops);
4a61c3e51e96a747c30598d78ee3a24e7c569e9fZbigniew Jędrzejewski-Szmek r = hashmap_put(s->daemons, &d->fd, d);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt log_error_errno(r, "Failed to add daemon to hashmap: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int setup_microhttpd_socket(RemoteServer *s,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering const char *trust) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM | SOCK_CLOEXEC);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return setup_microhttpd_server(s, fd, key, cert, trust);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int dispatch_http_event(sd_event_source *event,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering // XXX: unregister daemon
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering/**********************************************************************
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering **********************************************************************
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering **********************************************************************/
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int setup_signals(RemoteServer *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering sigset_add_many(&mask, SIGINT, SIGTERM, -1);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, NULL, s);
int fd, r;
if (fd > 0)
return -EINVAL;
return -fd;
const char* key,
const char* cert,
const char* trust) {
int r, n, fd;
char **file;
assert(s);
return -EINVAL;
setup_signals(s);
server = s;
r = init_writer_hashmap(s);
n = sd_listen_fds(true);
return -EBADFD;
char *hostname;
return -EINVAL;
fd);
if (arg_url) {
if (arg_getter) {
if (fd < 0)
return fd;
hostname =
if (arg_listen_raw) {
if (arg_listen_http) {
if (arg_listen_https) {
const char *output_name;
if (fd < 0)
if (s->active == 0) {
return -EINVAL;
size_t i;
MHDDaemonWrapper *d;
free(d);
for (i = 0; i < s->sources_size; i++)
remove_source(s, i);
int fd,
void *userdata) {
if (remaining > 0)
} else if (r == -E2BIG) {
void *userdata) {
int fd2, r;
if (fd2 < 0)
case AF_INET:
case AF_INET6: {
type,
*hostname = b;
return fd2;
return -EINVAL;
int fd,
void *userdata) {
int fd2;
char *hostname;
if (fd2 < 0)
return fd2;
static int parse_config(void) {
false, NULL);
static void help(void) {
help();
case ARG_VERSION:
case ARG_URL:
if (arg_url) {
return -EINVAL;
case ARG_GETTER:
if (arg_getter) {
return -EINVAL;
case ARG_LISTEN_RAW:
if (arg_listen_raw) {
return -EINVAL;
case ARG_LISTEN_HTTP:
return -EINVAL;
http_socket = r;
case ARG_LISTEN_HTTPS:
return -EINVAL;
https_socket = r;
case ARG_KEY:
if (arg_key) {
return -EINVAL;
if (!arg_key)
return log_oom();
case ARG_CERT:
if (arg_cert) {
return -EINVAL;
if (!arg_cert)
return log_oom();
case ARG_TRUST:
return -EINVAL;
arg_trust_all = true;
#ifdef HAVE_GNUTLS
if (!arg_trust)
return log_oom();
return -EINVAL;
if (arg_output) {
return -EINVAL;
case ARG_SPLIT_MODE:
return -EINVAL;
case ARG_COMPRESS:
if (optarg) {
return -EINVAL;
arg_compress = !!r;
arg_compress = true;
case ARG_SEAL:
if (optarg) {
return -EINVAL;
arg_seal = !!r;
arg_seal = true;
case ARG_GNUTLS_LOG: {
#ifdef HAVE_GNUTLS
char *cat;
if (!cat)
return log_oom();
return log_oom();
return -EINVAL;
return -EINVAL;
|| sd_listen_fds(false) > 0;
return -EINVAL;
if (type_a) {
if (!arg_output) {
return -EINVAL;
return -EINVAL;
return -EINVAL;
if (arg_trust_all)
#ifdef HAVE_GNUTLS
char **cat;
if (categories) {
RemoteServer s = {};
log_show_color(true);
r = parse_config();
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_FAILURE;
sd_notify(false,
while (s.active) {
if (r == SD_EVENT_FINISHED)
sd_notifyf(false,
server_destroy(&s);