+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
#include <sys/prctl.h>
#include <sys/socket.h>
#include <unistd.h>
+#include <stdint.h>
#include "sd-daemon.h"
static int http_socket = -1, https_socket = -1;
static char** arg_gnutls_log = NULL;
-static JournalWriteSplitMode arg_split_mode = JOURNAL_WRITE_SPLIT_HOST;
+static JournalWriteSplitMode arg_split_mode = _JOURNAL_WRITE_SPLIT_INVALID;
static char* arg_output = NULL;
static char *arg_key = NULL;
int fd,
uint32_t revents,
void *userdata);
+static int null_timer_event_handler(sd_event_source *s,
+ uint64_t usec,
+ void *userdata);
static int dispatch_http_event(sd_event_source *event,
int fd,
uint32_t revents,
{ MHD_OPTION_END},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
+ { MHD_OPTION_END},
{ MHD_OPTION_END}};
int opts_pos = 4;
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
MHD_USE_EPOLL |
- MHD_USE_PEDANTIC_CHECKS |
MHD_USE_ITC;
const union MHD_DaemonInfo *info;
if (r < 0)
return log_error_errno(r, "Failed to make fd:%d nonblocking: %m", fd);
+/* MHD_OPTION_STRICT_FOR_CLIENT is introduced in microhttpd 0.9.54,
+ * and MHD_USE_PEDANTIC_CHECKS will be deprecated in future.
+ * If MHD_USE_PEDANTIC_CHECKS is '#define'd, then it is deprecated
+ * and we should use MHD_OPTION_STRICT_FOR_CLIENT. On the other hand,
+ * if MHD_USE_PEDANTIC_CHECKS is not '#define'd, then it is not
+ * deprecated yet and there exists an enum element with the same name.
+ * So we can safely use it. */
+#ifdef MHD_USE_PEDANTIC_CHECKS
+ opts[opts_pos++] = (struct MHD_OptionItem)
+ {MHD_OPTION_STRICT_FOR_CLIENT, 1};
+#else
+ flags |= MHD_USE_PEDANTIC_CHECKS;
+#endif
+
if (key) {
assert(cert);
opts[opts_pos++] = (struct MHD_OptionItem)
{MHD_OPTION_HTTPS_MEM_CERT, 0, (char*) cert};
- flags |= MHD_USE_SSL;
+ flags |= MHD_USE_TLS;
if (trust)
opts[opts_pos++] = (struct MHD_OptionItem)
goto error;
}
- r = sd_event_add_io(s->events, &d->event,
+ r = sd_event_add_io(s->events, &d->io_event,
epoll_fd, EPOLLIN,
dispatch_http_event, d);
if (r < 0) {
goto error;
}
- r = sd_event_source_set_description(d->event, "epoll-fd");
+ r = sd_event_source_set_description(d->io_event, "io_event");
+ if (r < 0) {
+ log_error_errno(r, "Failed to set source name: %m");
+ goto error;
+ }
+
+ r = sd_event_add_time(s->events, &d->timer_event,
+ CLOCK_MONOTONIC, UINT64_MAX, 0,
+ null_timer_event_handler, d);
+ if (r < 0) {
+ log_error_errno(r, "Failed to add timer_event: %m");
+ goto error;
+ }
+
+ r = sd_event_source_set_description(d->timer_event, "timer_event");
if (r < 0) {
log_error_errno(r, "Failed to set source name: %m");
goto error;
return setup_microhttpd_server(s, fd, key, cert, trust);
}
+static int null_timer_event_handler(sd_event_source *timer_event,
+ uint64_t usec,
+ void *userdata) {
+ return dispatch_http_event(timer_event, 0, 0, userdata);
+}
+
static int dispatch_http_event(sd_event_source *event,
int fd,
uint32_t revents,
void *userdata) {
MHDDaemonWrapper *d = userdata;
int r;
+ MHD_UNSIGNED_LONG_LONG timeout = ULONG_LONG_MAX;
assert(d);
// XXX: unregister daemon
return -EINVAL;
}
+ if (MHD_get_timeout(d->daemon, &timeout) == MHD_NO)
+ timeout = ULONG_LONG_MAX;
+
+ r = sd_event_source_set_time(d->timer_event, timeout);
+ if (r < 0) {
+ log_warning_errno(r, "Unable to set event loop timeout: %m, this may result in indefinite blocking!");
+ return 1;
+ }
+
+ r = sd_event_source_set_enabled(d->timer_event, SD_EVENT_ON);
+ if (r < 0)
+ log_warning_errno(r, "Unable to enable timer_event: %m, this may result in indefinite blocking!");
return 1; /* work to do */
}
while ((d = hashmap_steal_first(s->daemons))) {
MHD_stop_daemon(d->daemon);
- sd_event_source_unref(d->event);
+ sd_event_source_unref(d->io_event);
+ sd_event_source_unref(d->timer_event);
free(d);
}
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
"Remote\0", config_item_table_lookup, items,
- false, NULL);
+ CONFIG_PARSE_WARN, NULL);
}
static void help(void) {
if (streq(optarg, "all"))
arg_trust_all = true;
else {
-#ifdef HAVE_GNUTLS
+#if HAVE_GNUTLS
arg_trust = strdup(optarg);
if (!arg_trust)
return log_oom();
break;
case ARG_GNUTLS_LOG: {
-#ifdef HAVE_GNUTLS
+#if HAVE_GNUTLS
const char* p = optarg;
for (;;) {
_cleanup_free_ char *word = NULL;
return -EINVAL;
}
+ if (!IN_SET(arg_split_mode, JOURNAL_WRITE_SPLIT_NONE, _JOURNAL_WRITE_SPLIT_INVALID)) {
+ log_error("For active sources, only --split-mode=none is allowed.");
+ return -EINVAL;
+ }
+
arg_split_mode = JOURNAL_WRITE_SPLIT_NONE;
}
- if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE
- && arg_output && is_dir(arg_output, true) > 0) {
- log_error("For SplitMode=none, output must be a file.");
- return -EINVAL;
+ if (arg_split_mode == _JOURNAL_WRITE_SPLIT_INVALID)
+ arg_split_mode = JOURNAL_WRITE_SPLIT_HOST;
+
+ if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE && arg_output) {
+ if (is_dir(arg_output, true) > 0) {
+ log_error("For SplitMode=none, output must be a file.");
+ return -EINVAL;
+ }
+ if (!endswith(arg_output, ".journal")) {
+ log_error("For SplitMode=none, output file name must end with .journal.");
+ return -EINVAL;
+ }
}
if (arg_split_mode == JOURNAL_WRITE_SPLIT_HOST