-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
#include <sys/socket.h>
#include <unistd.h>
-#ifdef HAVE_GNUTLS
-#include <gnutls/gnutls.h>
-#endif
-
#include "sd-daemon.h"
#include "alloc-util.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;
if (pipe(fd) < 0)
return log_error_errno(errno, "Failed to create pager pipe: %m");
- parent_pid = getpid();
+ parent_pid = getpid_cached();
child_pid = fork();
if (child_pid < 0) {
if (r < 0)
log_warning_errno(errno, "Failed to close write end of pipe: %m");
+ r = fd_nonblock(fd[0], true);
+ if (r < 0)
+ log_warning_errno(errno, "Failed to set child pipe to non-blocking: %m");
+
return fd[0];
}
return r;
}
-static int spawn_getter(const char *getter, const char *url) {
+static int spawn_getter(const char *getter) {
int r;
_cleanup_strv_free_ char **words = NULL;
if (r < 0)
return log_error_errno(r, "Failed to split getter option: %m");
- r = strv_extend(&words, url);
- if (r < 0)
- return log_error_errno(r, "Failed to create command line: %m");
-
r = spawn_child(words[0], words);
if (r < 0)
log_error_errno(r, "Failed to spawn getter %s: %m", getter);
O_RDWR|O_CREAT, 0640,
arg_compress, arg_seal,
&w->metrics,
- w->mmap,
+ w->mmap, NULL,
NULL, &w->journal);
if (r < 0)
log_error_errno(r, "Failed to open output journal %s: %m",
return r;
fd_ = -1;
- s->active ++;
+ s->active++;
return 0;
}
if (*upload_data_size) {
log_trace("Received %zu bytes", *upload_data_size);
- r = push_data(source, upload_data, *upload_data_size);
+ r = journal_importer_push_data(&source->importer,
+ upload_data, *upload_data_size);
if (r < 0)
return mhd_respond_oom(connection);
log_warning("Failed to process data for connection %p", connection);
if (r == -E2BIG)
return mhd_respondf(connection,
- MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
- "Entry is too large, maximum is %u bytes.\n",
- DATA_SIZE_MAX);
+ r, MHD_HTTP_PAYLOAD_TOO_LARGE,
+ "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
else
return mhd_respondf(connection,
- MHD_HTTP_UNPROCESSABLE_ENTITY,
- "Processing failed: %s.", strerror(-r));
+ r, MHD_HTTP_UNPROCESSABLE_ENTITY,
+ "Processing failed: %m.");
}
}
/* The upload is finished */
- remaining = source_non_empty(source);
+ remaining = journal_importer_bytes_remaining(&source->importer);
if (remaining > 0) {
- log_warning("Premature EOFbyte. %zu bytes lost.", remaining);
- return mhd_respondf(connection, MHD_HTTP_EXPECTATION_FAILED,
+ log_warning("Premature EOF byte. %zu bytes lost.", remaining);
+ return mhd_respondf(connection,
+ 0, MHD_HTTP_EXPECTATION_FAILED,
"Premature EOF. %zu bytes of trailing data not processed.",
remaining);
}
- return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.\n");
+ return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.");
};
static int request_handler(
*connection_cls);
if (!streq(method, "POST"))
- return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE,
- "Unsupported method.\n");
+ return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, "Unsupported method.");
if (!streq(url, "/upload"))
- return mhd_respond(connection, MHD_HTTP_NOT_FOUND,
- "Not found.\n");
+ return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found.");
header = MHD_lookup_connection_value(connection,
MHD_HEADER_KIND, "Content-Type");
if (!header || !streq(header, "application/vnd.fdo.journal"))
return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
- "Content-Type: application/vnd.fdo.journal"
- " is required.\n");
+ "Content-Type: application/vnd.fdo.journal is required.");
{
const union MHD_ConnectionInfo *ci;
if (!ci) {
log_error("MHD_get_connection_info failed: cannot get remote fd");
return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
- "Cannot check remote address");
+ "Cannot check remote address.");
}
fd = ci->connect_fd;
r = getpeername_pretty(fd, false, &hostname);
if (r < 0)
return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
- "Cannot check remote hostname");
+ "Cannot check remote hostname.");
}
assert(hostname);
if (r == -ENOMEM)
return respond_oom(connection);
else if (r < 0)
- return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
- strerror(-r));
+ return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "%m");
hostname = NULL;
return MHD_YES;
{ MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free},
{ MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger},
{ MHD_OPTION_LISTEN_SOCKET, fd},
- { MHD_OPTION_CONNECTION_MEMORY_LIMIT, DATA_SIZE_MAX},
+ { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024},
+ { MHD_OPTION_END},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
- MHD_USE_EPOLL_LINUX_ONLY |
- MHD_USE_PEDANTIC_CHECKS |
- MHD_USE_PIPE_FOR_SHUTDOWN;
+ MHD_USE_EPOLL |
+ MHD_USE_ITC;
const union MHD_DaemonInfo *info;
int r, epoll_fd;
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;
}
- s->active ++;
+ s->active++;
return 0;
error:
fd);
}
- if (arg_url) {
- const char *url, *hostname;
+ if (arg_getter) {
+ log_info("Spawning getter %s...", arg_getter);
+ fd = spawn_getter(arg_getter);
+ if (fd < 0)
+ return fd;
+
+ r = add_source(s, fd, (char*) arg_output, false);
+ if (r < 0)
+ return r;
+ }
- url = strjoina(arg_url, "/entries");
+ if (arg_url) {
+ const char *url;
+ char *hostname, *p;
- if (arg_getter) {
- log_info("Spawning getter %s...", url);
- fd = spawn_getter(arg_getter, url);
- } else {
- log_info("Spawning curl %s...", url);
- fd = spawn_curl(url);
+ if (!strstr(arg_url, "/entries")) {
+ if (endswith(arg_url, "/"))
+ url = strjoina(arg_url, "entries");
+ else
+ url = strjoina(arg_url, "/entries");
}
+ else
+ url = strdupa(arg_url);
+
+ log_info("Spawning curl %s...", url);
+ fd = spawn_curl(url);
if (fd < 0)
return fd;
startswith(arg_url, "http://") ?:
arg_url;
- r = add_source(s, fd, (char*) hostname, false);
+ hostname = strdupa(hostname);
+ if ((p = strchr(hostname, '/')))
+ *p = '\0';
+ if ((p = strchr(hostname, ':')))
+ *p = '\0';
+
+ r = add_source(s, fd, hostname, false);
if (r < 0)
return r;
}
assert(fd >= 0 && fd < (ssize_t) s->sources_size);
source = s->sources[fd];
- assert(source->fd == fd);
+ assert(source->importer.fd == fd);
r = process_source(source, arg_compress, arg_seal);
- if (source->state == STATE_EOF) {
+ if (journal_importer_eof(&source->importer)) {
size_t remaining;
- log_debug("EOF reached with source fd:%d (%s)",
- source->fd, source->name);
+ log_debug("EOF reached with source %s (fd=%d)",
+ source->importer.name, source->importer.fd);
- remaining = source_non_empty(source);
+ remaining = journal_importer_bytes_remaining(&source->importer);
if (remaining > 0)
log_notice("Premature EOF. %zu bytes lost.", remaining);
- remove_source(s, source->fd);
+ remove_source(s, source->importer.fd);
log_debug("%zu active sources remaining", s->active);
return 0;
} else if (r == -E2BIG) {
/* Make sure event stays around even if source is destroyed */
sd_event_source_ref(event);
- r = handle_raw_source(event, source->fd, EPOLLIN, server);
+ r = handle_raw_source(event, source->importer.fd, EPOLLIN, server);
if (r != 1)
/* No more data for now */
sd_event_source_set_enabled(event, SD_EVENT_OFF);
void *userdata) {
RemoteSource *source = userdata;
- return handle_raw_source(event, source->fd, EPOLLIN, server);
+ return handle_raw_source(event, source->importer.fd, EPOLLIN, server);
}
static int accept_connection(const char* type, int fd,
{ "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust },
{}};
- return config_parse_many(PKGSYSCONFDIR "/journal-remote.conf",
- CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
- "Remote\0", config_item_table_lookup, items,
- false, NULL);
+ 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);
}
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
if (r < 0)
log_error_errno(r, "Failed to enable watchdog: %m");
else
- log_debug("Watchdog is %s.", r > 0 ? "enabled" : "disabled");
+ log_debug("Watchdog is %sd.", enable_disable(r > 0));
log_debug("%s running as pid "PID_FMT,
- program_invocation_short_name, getpid());
+ program_invocation_short_name, getpid_cached());
sd_notify(false,
"READY=1\n"
"STATUS=Processing requests...");